--- a/jdk/make/Import.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/Import.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -34,11 +34,9 @@
ifneq ($(OPENJDK_TARGET_OS), windows)
HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
- SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent$(OPENJDK_TARGET_CPU_LIBDIR)
else
HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
- SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent
endif
################################################################################
@@ -58,10 +56,6 @@
Xusage.txt \
#
-HOTSPOT_SA_IMPORT_FILES := \
- $(addprefix $(LIBRARY_PREFIX), saproc.* sawindbg.*) \
- #
-
$(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE, \
SRC := $(HOTSPOT_LIB_DIR), \
DEST := $(BASE_INSTALL_LIBRARIES_HERE), \
@@ -77,14 +71,6 @@
BASE_TARGETS := $(COPY_HOTSPOT_BASE) $(COPY_HOTSPOT_BASE_JVMLIB)
-$(eval $(call SetupCopyFiles,COPY_HOTSPOT_SA, \
- SRC := $(HOTSPOT_LIB_DIR), \
- DEST := $(SA_INSTALL_LIBRARIES_HERE), \
- FILES := $(shell $(FIND) $(HOTSPOT_LIB_DIR) -type f \
- -a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE), $(HOTSPOT_SA_IMPORT_FILES)) \) )))
-
-SA_TARGETS := $(COPY_HOTSPOT_SA)
-
################################################################################
ifneq ($(STATIC_BUILD), true)
@@ -213,34 +199,6 @@
################################################################################
-$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked: $(HOTSPOT_DIST)/lib/sa-jdi.jar \
- $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
- $(ECHO) $(LOG_INFO) Unzipping $(<F)
- $(RM) -r $(@D)
- $(MKDIR) -p $(@D)
- $(CD) $(@D) && $(UNZIP) $< -x META-INF/MANIFEST.MF $(LOG_DEBUG)
- # We must move the service provider file out of the way so that
- # Gensrc-jdk.jdi.gmk can combine them.
- $(MKDIR) -p $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent
- $(MV) $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector \
- $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
- $(TOUCH) $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
- $(TOUCH) $@
-
-# Declaring this dependency guarantees that _the.sa.services will be rebuilt
-# even if zip is already unpacked.
-$(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services: $(HOTSPOT_DIST)/lib/sa-jdi.jar
-
-# Some platforms don't have the serviceability agent
-ifeq (, $(filter $(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), aix-ppc64))
- ifneq ($(JVM_VARIANT_ZERO), true)
- SA_TARGETS += $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/_the.sa.jar.unpacked \
- $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
- endif
-endif
-
-################################################################################
-
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupCopyFiles,BASE_COPY_LIBS_BIN, \
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
@@ -252,33 +210,16 @@
DEST := $(JDK_OUTPUTDIR)/lib, \
FILES := $(filter %.lib, $(BASE_TARGETS))))
- $(eval $(call SetupCopyFiles,SA_COPY_LIBS, \
- SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent, \
- DEST := $(JDK_OUTPUTDIR)/lib, \
- FILES := $(filter $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent/%, \
- $(SA_TARGETS))))
-
- $(eval $(call SetupCopyFiles,SA_COPY_LIBS, \
- SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent, \
- DEST := $(JDK_OUTPUTDIR)/bin, \
- FILES := $(filter $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent/%, \
- $(SA_TARGETS))))
else
$(eval $(call SetupCopyFiles,BASE_COPY_LIBS, \
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
DEST := $(JDK_OUTPUTDIR)/lib, \
FILES := $(BASE_TARGETS)))
-
- $(eval $(call SetupCopyFiles,SA_COPY_LIBS, \
- SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent, \
- DEST := $(JDK_OUTPUTDIR)/lib, \
- FILES := $(filter $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent/%, $(SA_TARGETS))))
endif
################################################################################
-all: $(BASE_TARGETS) $(SA_TARGETS) \
- $(BASE_COPY_LIBS_BIN) $(BASE_COPY_LIBS_LIB) \
- $(BASE_COPY_LIBS) $(SA_COPY_LIBS)
+all: $(BASE_TARGETS) $(BASE_COPY_LIBS_BIN) $(BASE_COPY_LIBS_LIB) \
+ $(BASE_COPY_LIBS)
.PHONY: default all
--- a/jdk/make/gendata/GendataBreakIterator.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/gendata/GendataBreakIterator.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -58,13 +58,13 @@
# output
BASE_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/java.base/sun/text/resources
-SL_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources
+LD_DATA_PKG_DIR := $(JDK_OUTPUTDIR)/modules/jdk.localedata/sun/text/resources
BIFILES := $(BASE_DATA_PKG_DIR)/CharacterBreakIteratorData \
$(BASE_DATA_PKG_DIR)/WordBreakIteratorData \
$(BASE_DATA_PKG_DIR)/LineBreakIteratorData \
$(BASE_DATA_PKG_DIR)/SentenceBreakIteratorData
-BIFILES_TH := $(SA_DATA_PKG_DIR)/th/WordBreakIteratorData_th \
- $(SA_DATA_PKG_DIR)/th/LineBreakIteratorData_th
+BIFILES_TH := $(LD_DATA_PKG_DIR)/th/WordBreakIteratorData_th \
+ $(LD_DATA_PKG_DIR)/th/LineBreakIteratorData_th
$(BIFILES): $(BASE_DATA_PKG_DIR)/_the.bifiles
$(BASE_DATA_PKG_DIR)/_the.bifiles: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
@@ -77,9 +77,9 @@
-spec $(UNICODEDATA)
$(TOUCH) $@
-$(BIFILES_TH): $(SL_DATA_PKG_DIR)/_the.bifiles_th
-$(SL_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
-$(SL_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR)
+$(BIFILES_TH): $(LD_DATA_PKG_DIR)/_the.bifiles_th
+$(LD_DATA_PKG_DIR)/_the.bifiles_th: JAVA_FLAGS += -Xbootclasspath/p:$(BREAK_ITERATOR_CLASSES)
+$(LD_DATA_PKG_DIR)/_the.bifiles_th: $(BUILD_TOOLS) $(UNICODEDATA) $(BUILD_BREAKITERATOR)
$(ECHO) $(LOG_INFO) "Generating BreakIteratorData_th"
$(MKDIR) -p $(@D)/th
$(RM) $(BIFILES_TH)
--- a/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -70,11 +70,11 @@
# Filter com.sun.jdi.connect.Connector
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector: \
$(JDK_TOPDIR)/src/jdk.jdi/share/classes/META-INF/services/com.sun.jdi.connect.Connector \
- $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/_the.sa.services
+ $(HOTSPOT_TOPDIR)/agent/src/share/classes/META-INF/services/com.sun.jdi.connect.Connector
$(process-provider)
# Copy the same service file into jdk.hotspot.agent so that they are kept the same.
-$(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector: \
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector: \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector
$(install-file)
@@ -82,7 +82,7 @@
ifeq (, $(filter $(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), aix-ppc64))
ifneq ($(JVM_VARIANT_ZERO), true)
GENSRC_JDK_JDI += $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/META-INF/services/com.sun.jdi.connect.Connector \
- $(JDK_OUTPUTDIR)/modules/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector
+ $(SUPPORT_OUTPUTDIR)/gensrc/jdk.hotspot.agent/META-INF/services/com.sun.jdi.connect.Connector
endif
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/Gensrc-jdk.jvmstat.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,55 @@
+#
+# 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.
+#
+
+include GensrcCommon.gmk
+
+################################################################################
+
+define merge-providers
+ $(MKDIR) -p $(@D)
+ $(CAT) $^ > $@
+endef
+
+PROVIDER_FILE := META-INF/services/sun.jvmstat.monitor.MonitoredHostService
+
+# Merge the local and remote sevice providers into jdk.jvmstat/META-INF/services
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE): \
+ $(JDK_TOPDIR)/src/jdk.jvmstat/share/classes/$(PROVIDER_FILE) \
+ $(JDK_TOPDIR)/src/jdk.jvmstat.rmi/share/classes/$(PROVIDER_FILE)
+ $(merge-providers)
+
+# Copy the same service file into jdk.jvmstat.rmi so that they are kept the same.
+$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE): \
+ $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE)
+ $(install-file)
+
+################################################################################
+
+jdk.jvmstat: $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat/$(PROVIDER_FILE) \
+ $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jvmstat.rmi/$(PROVIDER_FILE)
+
+all: jdk.jvmstat
+
+.PHONY: all
\ No newline at end of file
--- a/jdk/make/gensrc/GensrcCommon.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/gensrc/GensrcCommon.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -33,4 +33,3 @@
include SetupJavaCompilers.gmk
# We need the tools.
include Tools.gmk
-
--- a/jdk/make/gensrc/GensrcMisc.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/gensrc/GensrcMisc.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -90,7 +90,6 @@
SRC := $(GENSRC_UC_SRC), \
INCLUDE_FILES := $(GENSRC_UC_SRC_FILE), \
TOOLCHAIN := TOOLCHAIN_BUILD, \
- CFLAGS := $(filter -D%, $(CFLAGS_JDKEXE)), \
OBJECT_DIR := $(GENSRC_UC_BIN), \
OUTPUT_DIR := $(GENSRC_UC_BIN), \
PROGRAM := genUnixConstants))
--- a/jdk/make/gensrc/GensrcProperties.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/gensrc/GensrcProperties.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -75,7 +75,7 @@
# Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
# to .../support/gensrc/<module>/com/sun/tools/javac/resources/javac_zh_CN.java
- # Strip away prefix and suffix, leaving for example only:
+ # Strip away prefix and suffix, leaving for example only:
# "<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN"
$1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \
$(SUPPORT_OUTPUTDIR)/gensrc/%, \
--- a/jdk/make/launcher/Launcher-jdk.jcmd.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/launcher/Launcher-jdk.jcmd.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -30,7 +30,6 @@
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
- APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))
@@ -39,7 +38,6 @@
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
- APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))
@@ -52,7 +50,6 @@
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
- APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
MACOSX_SIGNED := true, \
))
--- a/jdk/make/launcher/Launcher-jdk.jconsole.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/launcher/Launcher-jdk.jconsole.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -28,7 +28,6 @@
$(eval $(call SetupBuildLauncher, jconsole, \
MAIN_CLASS := sun.tools.jconsole.JConsole, \
JAVA_ARGS := -Djconsole.showOutputViewer, \
- APP_CLASSPATH := /lib/jconsole.jar /lib/tools.jar /classes, \
CFLAGS_windows := -DJAVAW, \
LIBS_windows := user32.lib, \
))
--- a/jdk/make/launcher/Launcher-jdk.jdi.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/launcher/Launcher-jdk.jdi.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -27,5 +27,4 @@
$(eval $(call SetupBuildLauncher, jdb, \
MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \
- APP_CLASSPATH := /lib/tools.jar /lib/sa-jdi.jar /classes, \
))
--- a/jdk/make/launcher/Launcher-jdk.jvmstat.gmk Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2011, 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.
-#
-
-include LauncherCommon.gmk
-
-$(eval $(call SetupBuildLauncher, jstatd, \
- MAIN_CLASS := sun.tools.jstatd.Jstatd, \
-))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/launcher/Launcher-jdk.jvmstat.rmi.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2011, 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.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jstatd, \
+ MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+))
--- a/jdk/make/launcher/LauncherCommon.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/launcher/LauncherCommon.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -64,7 +64,6 @@
# Remaining parameters are named arguments. These include:
# MAIN_CLASS The Java main class to launch
# JAVA_ARGS Processed into a -DJAVA_ARGS C flag
-# APP_CLASSPATH Processed into a -DAPP_CLASSPATH C flag
# CFLAGS Additional CFLAGS
# CFLAGS_windows Additional CFLAGS_windows
# LIBS_unix Additional LIBS_unix
@@ -103,15 +102,6 @@
$1_CFLAGS += -DJAVA_ARGS=$$($1_JAVA_ARGS_STR)
endif
- ifneq ($$($1_APP_CLASSPATH), )
- $1_APP_CLASSPATH_STR := '{ $$(strip $$(foreach a, \
- $$($1_APP_CLASSPATH), "$$a"$(COMMA) )) }'
- # Remove the trailing comma
- $1_APP_CLASSPATH_STR := $$(strip $$(subst $$(COMMA) }', }', \
- $$($1_APP_CLASSPATH_STR)))
- $1_CFLAGS += -DAPP_CLASSPATH=$$($1_APP_CLASSPATH_STR)
- endif
-
$1_LIBS :=
ifeq ($(OPENJDK_TARGET_OS), macosx)
ifeq ($$($1_MACOSX_SIGNED), true)
--- a/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/lib/Lib-jdk.crypto.ucrypto.gmk Wed Dec 02 09:34:55 2015 -0800
@@ -43,7 +43,7 @@
LDFLAGS := $(LDFLAGS_JDKLIB), \
LIBS := $(LIBDL), \
LIBS_solaris := -lc, \
- OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libj2ucrypto, \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2ucrypto, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
$(BUILD_LIBJ2UCRYPTO): $(BUILD_LIBJAVA)
--- a/jdk/make/mapfiles/libjava/mapfile-vers Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Wed Dec 02 09:34:55 2015 -0800
@@ -138,9 +138,14 @@
Java_java_lang_Double_longBitsToDouble;
Java_java_lang_Double_doubleToRawLongBits;
Java_java_lang_reflect_Proxy_defineClass0;
- Java_java_lang_Shutdown_runAllFinalizers;
Java_java_lang_Float_intBitsToFloat;
Java_java_lang_Float_floatToRawIntBits;
+ Java_java_lang_StackFrameInfo_fillInStackFrames;
+ Java_java_lang_StackFrameInfo_setMethodInfo;
+ Java_java_lang_StackStreamFactory_checkStackWalkModes;
+ Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
+ Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
+ Java_java_lang_Shutdown_runAllFinalizers;
Java_java_lang_StrictMath_IEEEremainder;
Java_java_lang_StrictMath_acos;
Java_java_lang_StrictMath_asin;
--- a/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java Wed Dec 02 09:34:55 2015 -0800
@@ -89,7 +89,7 @@
}
// Filter out platform-unrelated ones. We only support
- // #ifdef, #ifndef, and #endif.
+ // #ifdef, #ifndef, #else, and #endif. Nesting not supported (yet).
int mode = 0; // 0: out of block, 1: in match, 2: in non-match
Iterator<String> iter = lines.iterator();
while (iter.hasNext()) {
@@ -105,7 +105,17 @@
}
iter.remove();
} else if (line.startsWith("#ifndef ")) {
- mode = line.endsWith(args[2])?2:1;
+ if (line.indexOf('-') > 0) {
+ mode = line.endsWith(args[2]+"-"+args[3]) ? 2 : 1;
+ } else {
+ mode = line.endsWith(args[2]) ? 2 : 1;
+ }
+ iter.remove();
+ } else if (line.startsWith("#else")) {
+ if (mode == 0) {
+ throw new IllegalStateException("#else not in #if block");
+ }
+ mode = 3 - mode;
iter.remove();
} else {
if (mode == 2) iter.remove();
@@ -150,7 +160,7 @@
List<String> args) throws IOException {
// parse property until EOL, not including line breaks
boolean first = true;
- while (!line.isEmpty()) {
+ while (line != null && !line.isEmpty()) {
if (!line.startsWith("#")) {
if (!line.endsWith(",\\") ||
(!first && line.contains("="))) {
@@ -169,6 +179,8 @@
lines.add(String.format("%"+numSpaces+"s", "") + arg + ",\\");
}
}
- lines.add(line);
+ if (line != null) {
+ lines.add(line);
+ }
}
}
--- a/jdk/make/src/classes/build/tools/module/boot.modules Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/src/classes/build/tools/module/boot.modules Wed Dec 02 09:34:55 2015 -0800
@@ -19,6 +19,7 @@
jdk.charsets
jdk.deploy
jdk.deploy.osx
+jdk.vm.cds
jdk.httpserver
jdk.jfr
jdk.management
--- a/jdk/make/src/classes/build/tools/module/ext.modules Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/make/src/classes/build/tools/module/ext.modules Wed Dec 02 09:34:55 2015 -0800
@@ -9,6 +9,7 @@
jdk.crypto.mscapi
jdk.crypto.pkcs11
jdk.crypto.ucrypto
+jdk.dynalink
jdk.localedata
jdk.naming.dns
jdk.scripting.nashorn
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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 sun.nio.ch;
+
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * Creates this platform's default SelectorProvider
+ */
+
+public class DefaultSelectorProvider {
+
+ /**
+ * Prevent instantiation.
+ */
+ private DefaultSelectorProvider() { }
+
+ /**
+ * Returns the default SelectorProvider.
+ */
+ public static SelectorProvider create() {
+ return new sun.nio.ch.PollSelectorProvider();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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 sun.nio.ch;
+
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * Creates this platform's default SelectorProvider
+ */
+
+public class DefaultSelectorProvider {
+
+ /**
+ * Prevent instantiation.
+ */
+ private DefaultSelectorProvider() { }
+
+ /**
+ * Returns the default SelectorProvider.
+ */
+ public static SelectorProvider create() {
+ return new sun.nio.ch.EPollSelectorProvider();
+ }
+
+}
--- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -272,22 +272,6 @@
// (Done collecting options from props.)
- boolean isClassFile(String name) {
- if (!name.endsWith(".class")) return false;
- for (String prefix = name; ; ) {
- if (passFiles.contains(prefix)) return false;
- int chop = prefix.lastIndexOf('/');
- if (chop < 0) break;
- prefix = prefix.substring(0, chop);
- }
- return true;
- }
-
- boolean isMetaInfFile(String name) {
- return name.startsWith("/" + Utils.METAINF) ||
- name.startsWith(Utils.METAINF);
- }
-
// Get a new package, based on the old one.
private void makeNextPackage() {
pkg.reset();
@@ -332,6 +316,29 @@
InFile(JarEntry je) {
this(null, je);
}
+ boolean isClassFile() {
+ if (!name.endsWith(".class")) {
+ return false;
+ }
+ for (String prefix = name;;) {
+ if (passFiles.contains(prefix)) {
+ return false;
+ }
+ int chop = prefix.lastIndexOf('/');
+ if (chop < 0) {
+ break;
+ }
+ prefix = prefix.substring(0, chop);
+ }
+ return true;
+ }
+ boolean isMetaInfFile() {
+ return name.startsWith("/" + Utils.METAINF)
+ || name.startsWith(Utils.METAINF);
+ }
+ boolean mustProcess() {
+ return !isMetaInfFile() && isClassFile();
+ }
long getInputLength() {
long len = (je != null)? je.getSize(): f.length();
assert(len >= 0) : this+".len="+len;
@@ -391,7 +398,7 @@
Package.File file = null;
// (5078608) : discount the resource files in META-INF
// from segment computation.
- long inflen = (isMetaInfFile(name))
+ long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength();
@@ -406,7 +413,7 @@
assert(je.isDirectory() == name.endsWith("/"));
- if (isClassFile(name)) {
+ if (inFile.mustProcess()) {
file = readClass(name, bits.getInputStream());
}
if (file == null) {
@@ -429,7 +436,7 @@
for (InFile inFile : inFiles) {
String name = inFile.name;
// (5078608) : discount the resource files completely from segmenting
- long inflen = (isMetaInfFile(name))
+ long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength() ;
if ((segmentSize += inflen) > segmentLimit) {
@@ -447,7 +454,7 @@
if (verbose > 1)
Utils.log.fine("Reading " + name);
Package.File file = null;
- if (isClassFile(name)) {
+ if (inFile.mustProcess()) {
file = readClass(name, strm);
if (file == null) {
strm.close();
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -54,6 +54,8 @@
import sun.reflect.ReflectionFactory;
import sun.reflect.misc.ReflectUtil;
+import static java.io.ObjectStreamField.*;
+
/**
* Serialization's descriptor for classes. It contains the name and
* serialVersionUID of the class. The ObjectStreamClass for a specific class
@@ -1519,62 +1521,15 @@
* if class names equal, false otherwise.
*/
private static boolean classNamesEqual(String name1, String name2) {
- name1 = name1.substring(name1.lastIndexOf('.') + 1);
- name2 = name2.substring(name2.lastIndexOf('.') + 1);
- return name1.equals(name2);
+ int idx1 = name1.lastIndexOf('.') + 1;
+ int idx2 = name2.lastIndexOf('.') + 1;
+ int len1 = name1.length() - idx1;
+ int len2 = name2.length() - idx2;
+ return len1 == len2 &&
+ name1.regionMatches(idx1, name2, idx2, len1);
}
/**
- * Returns JVM type signature for given primitive.
- */
- private static String getPrimitiveSignature(Class<?> cl) {
- if (cl == Integer.TYPE)
- return "I";
- else if (cl == Byte.TYPE)
- return "B";
- else if (cl == Long.TYPE)
- return "J";
- else if (cl == Float.TYPE)
- return "F";
- else if (cl == Double.TYPE)
- return "D";
- else if (cl == Short.TYPE)
- return "S";
- else if (cl == Character.TYPE)
- return "C";
- else if (cl == Boolean.TYPE)
- return "Z";
- else if (cl == Void.TYPE)
- return "V";
- else
- throw new InternalError();
- }
-
- /**
- * Returns JVM type signature for given class.
- */
- static String getClassSignature(Class<?> cl) {
- if (cl.isPrimitive())
- return getPrimitiveSignature(cl);
- else
- return appendClassSignature(new StringBuilder(), cl).toString();
- }
-
- private static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
- while (cl.isArray()) {
- sbuf.append('[');
- cl = cl.getComponentType();
- }
-
- if (cl.isPrimitive())
- sbuf.append(getPrimitiveSignature(cl));
- else
- sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
-
- return sbuf;
- }
-
- /**
* Returns JVM type signature for given list of parameters and return type.
*/
private static String getMethodSignature(Class<?>[] paramTypes,
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamField.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -91,7 +91,7 @@
this.name = name;
this.type = type;
this.unshared = unshared;
- signature = ObjectStreamClass.getClassSignature(type).intern();
+ signature = getClassSignature(type).intern();
field = null;
}
@@ -124,6 +124,58 @@
}
/**
+ * Returns JVM type signature for given primitive.
+ */
+ private static String getPrimitiveSignature(Class<?> cl) {
+ if (cl == Integer.TYPE)
+ return "I";
+ else if (cl == Byte.TYPE)
+ return "B";
+ else if (cl == Long.TYPE)
+ return "J";
+ else if (cl == Float.TYPE)
+ return "F";
+ else if (cl == Double.TYPE)
+ return "D";
+ else if (cl == Short.TYPE)
+ return "S";
+ else if (cl == Character.TYPE)
+ return "C";
+ else if (cl == Boolean.TYPE)
+ return "Z";
+ else if (cl == Void.TYPE)
+ return "V";
+ else
+ throw new InternalError();
+ }
+
+ /**
+ * Returns JVM type signature for given class.
+ */
+ static String getClassSignature(Class<?> cl) {
+ if (cl.isPrimitive()) {
+ return getPrimitiveSignature(cl);
+ } else {
+ return appendClassSignature(new StringBuilder(), cl).toString();
+ }
+ }
+
+ static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
+ while (cl.isArray()) {
+ sbuf.append('[');
+ cl = cl.getComponentType();
+ }
+
+ if (cl.isPrimitive()) {
+ sbuf.append(getPrimitiveSignature(cl));
+ } else {
+ sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
+ }
+
+ return sbuf;
+ }
+
+ /**
* Creates an ObjectStreamField representing the given field with the
* specified unshared setting. For compatibility with the behavior of
* earlier serialization implementations, a "showType" parameter is
@@ -137,7 +189,7 @@
name = field.getName();
Class<?> ftype = field.getType();
type = (showType || ftype.isPrimitive()) ? ftype : Object.class;
- signature = ObjectStreamClass.getClassSignature(ftype).intern();
+ signature = getClassSignature(ftype).intern();
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Wed Dec 02 09:34:55 2015 -0800
@@ -732,13 +732,7 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(int i) {
- if (i == Integer.MIN_VALUE) {
- append("-2147483648");
- return this;
- }
- int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
- : Integer.stringSize(i);
- int spaceNeeded = count + appendedLength;
+ int spaceNeeded = count + Integer.stringSize(i);
ensureCapacityInternal(spaceNeeded);
if (isLatin1()) {
Integer.getChars(i, spaceNeeded, value);
@@ -764,13 +758,7 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(long l) {
- if (l == Long.MIN_VALUE) {
- append("-9223372036854775808");
- return this;
- }
- int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
- : Long.stringSize(l);
- int spaceNeeded = count + appendedLength;
+ int spaceNeeded = count + Long.stringSize(l);
ensureCapacityInternal(spaceNeeded);
if (isLatin1()) {
Long.getChars(l, spaceNeeded, value);
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java Wed Dec 02 09:34:55 2015 -0800
@@ -396,7 +396,7 @@
} while (charPos > offset);
}
- static final char [] DigitTens = {
+ static final byte[] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
@@ -409,7 +409,7 @@
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
} ;
- static final char [] DigitOnes = {
+ static final byte[] DigitOnes = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
@@ -422,21 +422,6 @@
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
} ;
- // I use the "invariant division by multiplication" trick to
- // accelerate Integer.toString. In particular we want to
- // avoid division by 10.
- //
- // The "trick" has roughly the same performance characteristics
- // as the "classic" Integer.toString code on a non-JIT VM.
- // The trick avoids .rem and .div calls but has a longer code
- // path and is thus dominated by dispatch overhead. In the
- // JIT case the dispatch overhead doesn't exist and the
- // "trick" is considerably faster than the classic code.
- //
- // RE: Division by Invariant Integers using Multiplication
- // T Gralund, P Montgomery
- // ACM PLDI 1994
- //
/**
* Returns a {@code String} object representing the
@@ -450,9 +435,7 @@
*/
@HotSpotIntrinsicCandidate
public static String toString(int i) {
- if (i == Integer.MIN_VALUE)
- return "-2147483648";
- int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+ int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
@@ -489,84 +472,105 @@
* digit at the specified index (exclusive), and working
* backwards from there.
*
- * Will fail if i == Integer.MIN_VALUE
+ * @implNote This method converts positive inputs into negative
+ * values, to cover the Integer.MIN_VALUE case. Converting otherwise
+ * (negative to positive) will expose -Integer.MIN_VALUE that overflows
+ * integer.
*/
static void getChars(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
- char sign = 0;
- if (i < 0) {
- sign = '-';
+ boolean negative = i < 0;
+ if (!negative) {
i = -i;
}
// Generate two digits per iteration
- while (i >= 65536) {
+ while (i <= -100) {
q = i / 100;
- // really: r = i - (q * 100);
- r = i - ((q << 6) + (q << 5) + (q << 2));
+ r = (q * 100) - i;
i = q;
- buf [--charPos] = (byte)DigitOnes[r];
- buf [--charPos] = (byte)DigitTens[r];
+ buf[--charPos] = DigitOnes[r];
+ buf[--charPos] = DigitTens[r];
}
- // Fall thru to fast mode for smaller numbers
- // assert(i <= 65536, i);
- for (;;) {
- q = (i * 52429) >>> (16+3);
- r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
- buf [--charPos] = (byte)digits [r];
- i = q;
- if (i == 0) break;
+ // We know there are at most two digits left at this point.
+ q = i / 10;
+ r = (q * 10) - i;
+ buf[--charPos] = (byte)('0' + r);
+
+ // Whatever left is the remaining digit.
+ if (q < 0) {
+ buf[--charPos] = (byte)('0' - q);
}
- if (sign != 0) {
- buf [--charPos] = (byte)sign;
+
+ if (negative) {
+ buf[--charPos] = (byte)'-';
}
}
static void getCharsUTF16(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
- char sign = 0;
- if (i < 0) {
- sign = '-';
+ boolean negative = (i < 0);
+ if (!negative) {
i = -i;
}
- // Generate two digits per iteration
- while (i >= 65536) {
+ // Get 2 digits/iteration using ints
+ while (i <= -100) {
q = i / 100;
- // really: r = i - (q * 100);
- r = i - ((q << 6) + (q << 5) + (q << 2));
+ r = (q * 100) - i;
i = q;
StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, DigitTens[r]);
}
- // Fall thru to fast mode for smaller numbers
- // assert(i <= 65536, i);
- for (;;) {
- q = (i * 52429) >>> (16+3);
- r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
- StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
- i = q;
- if (i == 0) break;
+ // We know there are at most two digits left at this point.
+ q = i / 10;
+ r = (q * 10) - i;
+ StringUTF16.putChar(buf, --charPos, '0' + r);
+
+ // Whatever left is the remaining digit.
+ if (q < 0) {
+ StringUTF16.putChar(buf, --charPos, '0' - q);
}
- if (sign != 0) {
- StringUTF16.putChar(buf, --charPos, sign);
+
+ if (negative) {
+ StringUTF16.putChar(buf, --charPos, '-');
}
}
+ // Left here for compatibility reasons, see JDK-8143900.
static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
- // Requires positive x
+ /**
+ * Returns the string representation size for a given int value.
+ *
+ * @param x int value
+ * @return string size
+ *
+ * @implNote There are other ways to compute this: e.g. binary search,
+ * but values are biased heavily towards zero, and therefore linear search
+ * wins. The iteration results are also routinely inlined in the generated
+ * code after loop unrolling.
+ */
static int stringSize(int x) {
- for (int i=0; ; i++)
- if (x <= sizeTable[i])
- return i+1;
+ int d = 1;
+ if (x >= 0) {
+ d = 0;
+ x = -x;
+ }
+ int p = -10;
+ for (int i = 1; i < 10; i++) {
+ if (x > p)
+ return i + d;
+ p = 10 * p;
+ }
+ return 10 + d;
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,226 @@
+/*
+ * 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 java.lang;
+
+import java.lang.StackWalker.StackFrame;
+import java.util.EnumSet;
+import java.util.Set;
+
+import static java.lang.StackWalker.ExtendedOption.LOCALS_AND_OPERANDS;
+
+/**
+ * <em>UNSUPPORTED</em> This interface is intended to be package-private
+ * or move to an internal package.<p>
+ *
+ * {@code LiveStackFrame} represents a frame storing data and partial results.
+ * Each frame has its own array of local variables (JVMS section 2.6.1),
+ * its own operand stack (JVMS section 2.6.2) for a method invocation.
+ *
+ * @jvms 2.6 Frames
+ */
+/* package-private */
+interface LiveStackFrame extends StackFrame {
+ /**
+ * Return the monitors held by this stack frame. This method returns
+ * an empty array if no monitor is held by this stack frame.
+ *
+ * @return the monitors held by this stack frames
+ */
+ public Object[] getMonitors();
+
+ /**
+ * Gets the local variable array of this stack frame.
+ *
+ * <p>A single local variable can hold a value of type boolean, byte, char,
+ * short, int, float, reference or returnAddress. A pair of local variables
+ * can hold a value of type long or double. In other words,
+ * a value of type long or type double occupies two consecutive local
+ * variables. For a value of primitive type, the element in the
+ * local variable array is an {@link PrimitiveValue} object;
+ * otherwise, the element is an {@code Object}.
+ *
+ * @return the local variable array of this stack frame.
+ */
+ public Object[] getLocals();
+
+ /**
+ * Gets the operand stack of this stack frame.
+ *
+ * <p>
+ * The 0-th element of the returned array represents the top of the operand stack.
+ * This method returns an empty array if the operand stack is empty.
+ *
+ * <p>Each entry on the operand stack can hold a value of any Java Virtual
+ * Machine Type.
+ * For a value of primitive type, the element in the returned array is
+ * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object}
+ * on the operand stack.
+ *
+ * @return the operand stack of this stack frame.
+ */
+ public Object[] getStack();
+
+ /**
+ * <em>UNSUPPORTED</em> This interface is intended to be package-private
+ * or move to an internal package.<p>
+ *
+ * Represents a local variable or an entry on the operand whose value is
+ * of primitive type.
+ */
+ public abstract class PrimitiveValue {
+ /**
+ * Returns the base type of this primitive value, one of
+ * {@code B, D, C, F, I, J, S, Z}.
+ *
+ * @return Name of a base type
+ * @jvms table 4.3-A
+ */
+ abstract char type();
+
+ /**
+ * Returns the boolean value if this primitive value is of type boolean.
+ * @return the boolean value if this primitive value is of type boolean.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type boolean.
+ */
+ public boolean booleanValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the int value if this primitive value is of type int.
+ * @return the int value if this primitive value is of type int.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type int.
+ */
+ public int intValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the long value if this primitive value is of type long.
+ * @return the long value if this primitive value is of type long.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type long.
+ */
+ public long longValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the char value if this primitive value is of type char.
+ * @return the char value if this primitive value is of type char.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type char.
+ */
+ public char charValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the byte value if this primitive value is of type byte.
+ * @return the byte value if this primitive value is of type byte.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type byte.
+ */
+ public byte byteValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the short value if this primitive value is of type short.
+ * @return the short value if this primitive value is of type short.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type short.
+ */
+ public short shortValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the float value if this primitive value is of type float.
+ * @return the float value if this primitive value is of type float.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type float.
+ */
+ public float floatValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+
+ /**
+ * Returns the double value if this primitive value is of type double.
+ * @return the double value if this primitive value is of type double.
+ *
+ * @throws UnsupportedOperationException if this primitive value is not
+ * of type double.
+ */
+ public double doubleValue() {
+ throw new UnsupportedOperationException("this primitive of type " + type());
+ }
+ }
+
+
+ /**
+ * Gets {@code StackWalker} that can get locals and operands.
+ *
+ * @throws SecurityException if the security manager is present and
+ * denies access to {@code RuntimePermission("liveStackFrames")}
+ */
+ public static StackWalker getStackWalker() {
+ return getStackWalker(EnumSet.noneOf(StackWalker.Option.class));
+ }
+
+ /**
+ * Gets a {@code StackWalker} instance with the given options specifying
+ * the stack frame information it can access, and which will traverse at most
+ * the given {@code maxDepth} number of stack frames. If no option is
+ * specified, this {@code StackWalker} obtains the method name and
+ * the class name with all
+ * {@linkplain StackWalker.Option#SHOW_HIDDEN_FRAMES hidden frames} skipped.
+ * The returned {@code StackWalker} can get locals and operands.
+ *
+ * @param options stack walk {@link StackWalker.Option options}
+ *
+ * @throws SecurityException if the security manager is present and
+ * it denies access to {@code RuntimePermission("liveStackFrames")}; or
+ * or if the given {@code options} contains
+ * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE}
+ * and it denies access to {@code StackFramePermission("retainClassReference")}.
+ */
+ public static StackWalker getStackWalker(Set<StackWalker.Option> options) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("liveStackFrames"));
+ }
+ return StackWalker.newInstance(options, LOCALS_AND_OPERANDS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,271 @@
+/*
+ * 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 java.lang;
+
+import java.lang.StackWalker.Option;
+import java.util.EnumSet;
+import java.util.Set;
+
+import static java.lang.StackWalker.ExtendedOption.*;
+
+final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame {
+ private static Object[] EMPTY_ARRAY = new Object[0];
+
+ LiveStackFrameInfo(StackWalker walker) {
+ super(walker);
+ }
+
+ // These fields are initialized by the VM if ExtendedOption.LOCALS_AND_OPERANDS is set
+ private Object[] monitors = EMPTY_ARRAY;
+ private Object[] locals = EMPTY_ARRAY;
+ private Object[] operands = EMPTY_ARRAY;
+
+ @Override
+ public Object[] getMonitors() {
+ return monitors;
+ }
+
+ @Override
+ public Object[] getLocals() {
+ return locals;
+ }
+
+ @Override
+ public Object[] getStack() {
+ return operands;
+ }
+
+ /*
+ * Convert primitive value to {@code Primitive} object to represent
+ * a local variable or an element on the operand stack of primitive type.
+ */
+ static PrimitiveValue asPrimitive(boolean value) {
+ return new BooleanPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(int value) {
+ return new IntPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(short value) {
+ return new ShortPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(char value) {
+ return new CharPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(byte value) {
+ return new BytePrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(long value) {
+ return new LongPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(float value) {
+ return new FloatPrimitive(value);
+ }
+
+ static PrimitiveValue asPrimitive(double value) {
+ return new DoublePrimitive(value);
+ }
+
+ private static class IntPrimitive extends PrimitiveValue {
+ final int value;
+ IntPrimitive(int value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'I';
+ }
+
+ @Override
+ public int intValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class ShortPrimitive extends PrimitiveValue {
+ final short value;
+ ShortPrimitive(short value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'S';
+ }
+
+ @Override
+ public short shortValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class BooleanPrimitive extends PrimitiveValue {
+ final boolean value;
+ BooleanPrimitive(boolean value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'Z';
+ }
+
+ @Override
+ public boolean booleanValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class CharPrimitive extends PrimitiveValue {
+ final char value;
+ CharPrimitive(char value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'C';
+ }
+
+ @Override
+ public char charValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class BytePrimitive extends PrimitiveValue {
+ final byte value;
+ BytePrimitive(byte value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'B';
+ }
+
+ @Override
+ public byte byteValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class LongPrimitive extends PrimitiveValue {
+ final long value;
+ LongPrimitive(long value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'J';
+ }
+
+ @Override
+ public long longValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class FloatPrimitive extends PrimitiveValue {
+ final float value;
+ FloatPrimitive(float value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'F';
+ }
+
+ @Override
+ public float floatValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+
+ private static class DoublePrimitive extends PrimitiveValue {
+ final double value;
+ DoublePrimitive(double value) {
+ this.value = value;
+ }
+
+ @Override
+ public char type() {
+ return 'D';
+ }
+
+ @Override
+ public double doubleValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/java/lang/Long.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java Wed Dec 02 09:34:55 2015 -0800
@@ -448,9 +448,7 @@
* @return a string representation of the argument in base 10.
*/
public static String toString(long i) {
- if (i == Long.MIN_VALUE)
- return "-9223372036854775808";
- int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
+ int size = stringSize(i);
if (COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
@@ -481,58 +479,59 @@
}
/**
- * Places characters representing the integer i into the
+ * Places characters representing the long i into the
* character array buf. The characters are placed into
* the buffer backwards starting with the least significant
* digit at the specified index (exclusive), and working
* backwards from there.
*
- * Will fail if i == Long.MIN_VALUE
+ * @implNote This method converts positive inputs into negative
+ * values, to cover the Long.MIN_VALUE case. Converting otherwise
+ * (negative to positive) will expose -Long.MIN_VALUE that overflows
+ * long.
*/
static void getChars(long i, int index, byte[] buf) {
long q;
int r;
int charPos = index;
- char sign = 0;
- if (i < 0) {
- sign = '-';
+ boolean negative = (i < 0);
+ if (!negative) {
i = -i;
}
// Get 2 digits/iteration using longs until quotient fits into an int
- while (i > Integer.MAX_VALUE) {
+ while (i <= Integer.MIN_VALUE) {
q = i / 100;
- // really: r = i - (q * 100);
- r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+ r = (int)((q * 100) - i);
i = q;
- buf[--charPos] = (byte)Integer.DigitOnes[r];
- buf[--charPos] = (byte)Integer.DigitTens[r];
+ buf[--charPos] = Integer.DigitOnes[r];
+ buf[--charPos] = Integer.DigitTens[r];
}
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
- while (i2 >= 65536) {
+ while (i2 <= -100) {
q2 = i2 / 100;
- // really: r = i2 - (q * 100);
- r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+ r = (q2 * 100) - i2;
i2 = q2;
- buf[--charPos] = (byte)Integer.DigitOnes[r];
- buf[--charPos] = (byte)Integer.DigitTens[r];
+ buf[--charPos] = Integer.DigitOnes[r];
+ buf[--charPos] = Integer.DigitTens[r];
}
- // Fall thru to fast mode for smaller numbers
- // assert(i2 <= 65536, i2);
- for (;;) {
- q2 = (i2 * 52429) >>> (16+3);
- r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
- buf[--charPos] = (byte)Integer.digits[r];
- i2 = q2;
- if (i2 == 0) break;
+ // We know there are at most two digits left at this point.
+ q2 = i2 / 10;
+ r = (q2 * 10) - i2;
+ buf[--charPos] = (byte)('0' + r);
+
+ // Whatever left is the remaining digit.
+ if (q2 < 0) {
+ buf[--charPos] = (byte)('0' - q2);
}
- if (sign != 0) {
- buf[--charPos] = (byte)sign;
+
+ if (negative) {
+ buf[--charPos] = (byte)'-';
}
}
@@ -540,18 +539,16 @@
long q;
int r;
int charPos = index;
- char sign = 0;
- if (i < 0) {
- sign = '-';
+ boolean negative = (i < 0);
+ if (!negative) {
i = -i;
}
// Get 2 digits/iteration using longs until quotient fits into an int
- while (i > Integer.MAX_VALUE) {
+ while (i <= Integer.MIN_VALUE) {
q = i / 100;
- // really: r = i - (q * 100);
- r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+ r = (int)((q * 100) - i);
i = q;
StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
@@ -560,38 +557,53 @@
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
- while (i2 >= 65536) {
+ while (i2 <= -100) {
q2 = i2 / 100;
- // really: r = i2 - (q * 100);
- r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+ r = (q2 * 100) - i2;
i2 = q2;
StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
}
- // Fall thru to fast mode for smaller numbers
- // assert(i2 <= 65536, i2);
- for (;;) {
- q2 = (i2 * 52429) >>> (16+3);
- r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
- StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
- i2 = q2;
- if (i2 == 0) break;
+ // We know there are at most two digits left at this point.
+ q2 = i2 / 10;
+ r = (q2 * 10) - i2;
+ StringUTF16.putChar(buf, --charPos, '0' + r);
+
+ // Whatever left is the remaining digit.
+ if (q2 < 0) {
+ StringUTF16.putChar(buf, --charPos, '0' - q2);
}
- if (sign != 0) {
- StringUTF16.putChar(buf, --charPos, sign);
+
+ if (negative) {
+ StringUTF16.putChar(buf, --charPos, '-');
}
}
- // Requires positive x
+ /**
+ * Returns the string representation size for a given long value.
+ *
+ * @param x long value
+ * @return string size
+ *
+ * @implNote There are other ways to compute this: e.g. binary search,
+ * but values are biased heavily towards zero, and therefore linear search
+ * wins. The iteration results are also routinely inlined in the generated
+ * code after loop unrolling.
+ */
static int stringSize(long x) {
- long p = 10;
- for (int i=1; i<19; i++) {
- if (x < p)
- return i;
- p = 10*p;
+ int d = 1;
+ if (x >= 0) {
+ d = 0;
+ x = -x;
}
- return 19;
+ long p = -10;
+ for (int i = 1; i < 19; i++) {
+ if (x > p)
+ return i + d;
+ p = 10 * p;
+ }
+ return 19 + d;
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -359,7 +359,14 @@
@Override
public Stream<ProcessHandle> children() {
- return children(pid);
+ // The native OS code selects based on matching the requested parent pid.
+ // If the original parent exits, the pid may have been re-used for
+ // this newer process.
+ // Processes started by the original parent (now dead) will all have
+ // start times less than the start of this newer parent.
+ // Processes started by this newer parent will have start times equal
+ // or after this parent.
+ return children(pid).filter(ph -> startTime <= ((ProcessHandleImpl)ph).startTime);
}
/**
@@ -408,11 +415,21 @@
int next = 0; // index of next process to check
int count = -1; // count of subprocesses scanned
long ppid = pid; // start looking for this parent
+ long ppStart = 0;
+ // Find the start time of the parent
+ for (int i = 0; i < size; i++) {
+ if (pids[i] == ppid) {
+ ppStart = starttimes[i];
+ break;
+ }
+ }
do {
- // Scan from next to size looking for ppid
- // if found, exchange it to index next
+ // Scan from next to size looking for ppid with child start time
+ // the same or later than the parent.
+ // If found, exchange it with index next
for (int i = next; i < size; i++) {
- if (ppids[i] == ppid) {
+ if (ppids[i] == ppid &&
+ ppStart <= starttimes[i]) {
swap(pids, i, next);
swap(ppids, i, next);
swap(starttimes, i, next);
@@ -420,6 +437,7 @@
}
}
ppid = pids[++count]; // pick up the next pid to scan for
+ ppStart = starttimes[count]; // and its start time
} while (count < next);
final long[] cpids = pids;
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java Wed Dec 02 09:34:55 2015 -0800
@@ -44,7 +44,7 @@
*/
public class Runtime {
- private static Runtime currentRuntime = new Runtime();
+ private static final Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.lang;
+
+import jdk.internal.misc.JavaLangInvokeAccess;
+import jdk.internal.misc.SharedSecrets;
+
+import static java.lang.StackWalker.Option.*;
+import java.lang.StackWalker.StackFrame;
+import java.util.Optional;
+import java.util.OptionalInt;
+
+class StackFrameInfo implements StackFrame {
+ private final static JavaLangInvokeAccess jlInvokeAccess =
+ SharedSecrets.getJavaLangInvokeAccess();
+
+ // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields;
+ // otherwise, VM will set the hidden fields (injected by the VM).
+ // -XX:+MemberNameInStackFrame is temporary to enable performance measurement
+ //
+ // Footprint improvement: MemberName::clazz and MemberName::name
+ // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName
+ // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name
+
+ final StackWalker walker;
+ final Class<?> declaringClass;
+ final Object memberName;
+ final int bci;
+
+ // methodName, fileName, and lineNumber will be lazily set by the VM
+ // when first requested.
+ private String methodName;
+ private String fileName = null; // default for unavailable filename
+ private int lineNumber = -1; // default for unavailable lineNumber
+
+ /*
+ * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
+ * to use
+ */
+ StackFrameInfo(StackWalker walker) {
+ this.walker = walker;
+ this.declaringClass = null;
+ this.bci = -1;
+ this.memberName = jlInvokeAccess.newMemberName();
+ }
+
+ @Override
+ public String getClassName() {
+ return declaringClass.getName();
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
+ return declaringClass;
+ }
+
+ // Call the VM to set methodName, lineNumber, and fileName
+ private synchronized void ensureMethodInfoInitialized() {
+ if (methodName == null) {
+ setMethodInfo();
+ }
+ }
+
+ @Override
+ public String getMethodName() {
+ ensureMethodInfoInitialized();
+ return methodName;
+ }
+
+ @Override
+ public Optional<String> getFileName() {
+ ensureMethodInfoInitialized();
+ return fileName != null ? Optional.of(fileName) : Optional.empty();
+ }
+
+ @Override
+ public OptionalInt getLineNumber() {
+ ensureMethodInfoInitialized();
+ return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty();
+ }
+
+ @Override
+ public boolean isNativeMethod() {
+ ensureMethodInfoInitialized();
+ return lineNumber == -2;
+ }
+
+ @Override
+ public String toString() {
+ ensureMethodInfoInitialized();
+ // similar format as StackTraceElement::toString
+ if (isNativeMethod()) {
+ return getClassName() + "." + getMethodName() + "(Native Method)";
+ } else {
+ // avoid allocating Optional objects
+ return getClassName() + "." + getMethodName() +
+ "(" + (fileName != null ? fileName : "Unknown Source") +
+ (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")";
+ }
+ }
+
+ /**
+ * Lazily initialize method name, file name, line number
+ */
+ private native void setMethodInfo();
+
+ /**
+ * Fill in source file name and line number of the given StackFrame array.
+ */
+ static native void fillInStackFrames(int startIndex,
+ Object[] stackframes,
+ int fromIndex, int toIndex);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackFramePermission.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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 java.lang;
+
+/**
+ * Permission to access {@link StackWalker.StackFrame}.
+ *
+ * @see java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE
+ * @see StackWalker.StackFrame#getDeclaringClass()
+ */
+public class StackFramePermission extends java.security.BasicPermission {
+ private static final long serialVersionUID = 2841894854386706014L;
+
+ /**
+ * Creates a new {@code StackFramePermission} object.
+ *
+ * @param name Permission name. Must be "retainClassReference".
+ *
+ * @throws IllegalArgumentException if {@code name} is invalid.
+ * @throws NullPointerException if {@code name} is {@code null}.
+ */
+ public StackFramePermission(String name) {
+ super(name);
+ if (!name.equals("retainClassReference")) {
+ throw new IllegalArgumentException("name: " + name);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,1106 @@
+/*
+ * 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 java.lang;
+
+import sun.misc.VM;
+
+import java.io.PrintStream;
+import java.lang.StackWalker.Option;
+import java.lang.StackWalker.StackFrame;
+
+import java.lang.annotation.Native;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import static java.lang.StackStreamFactory.WalkerState.*;
+
+/**
+ * StackStreamFactory class provides static factory methods
+ * to get different kinds of stack walker/traverser.
+ *
+ * AbstractStackWalker provides the basic stack walking support
+ * fetching stack frames from VM in batches.
+ *
+ * AbstractStackWalker subclass is specialized for a specific kind of stack traversal
+ * to avoid overhead of Stream/Lambda
+ * 1. Support traversing Stream<StackFrame>
+ * 2. StackWalker::getCallerClass
+ * 3. Throwable::init and Throwable::getStackTrace
+ * 4. AccessControlContext getting ProtectionDomain
+ */
+final class StackStreamFactory {
+ private StackStreamFactory() {}
+
+ // Stack walk implementation classes to be excluded during stack walking
+ // lazily add subclasses when they are loaded.
+ private final static Set<Class<?>> stackWalkImplClasses = init();
+
+ private static final int SMALL_BATCH = 8;
+ private static final int BATCH_SIZE = 32;
+ private static final int LARGE_BATCH_SIZE = 256;
+ private static final int MIN_BATCH_SIZE = SMALL_BATCH;
+
+ // These flags must match the values maintained in the VM
+ @Native private static final int DEFAULT_MODE = 0x0;
+ @Native private static final int FILL_CLASS_REFS_ONLY = 0x2;
+ @Native private static final int FILTER_FILL_IN_STACKTRACE = 0x10;
+ @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM
+ @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100;
+
+ /*
+ * For Throwable to use StackWalker, set useNewThrowable to true.
+ * Performance work and extensive testing is needed to replace the
+ * VM built-in backtrace filled in Throwable with the StackWalker.
+ */
+ final static boolean useNewThrowable = getProperty("stackwalk.newThrowable", false);
+ final static boolean isDebug = getProperty("stackwalk.debug", false);
+
+ static <T> StackFrameTraverser<T>
+ makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
+ {
+ if (walker.hasLocalsOperandsOption())
+ return new LiveStackInfoTraverser<T>(walker, function);
+ else
+ return new StackFrameTraverser<T>(walker, function);
+ }
+
+ /**
+ * Gets a stack stream to find caller class.
+ */
+ static CallerClassFinder makeCallerFinder(StackWalker walker) {
+ return new CallerClassFinder(walker);
+ }
+
+ static boolean useStackTrace(Throwable t) {
+ if (t instanceof VirtualMachineError)
+ return false;
+
+ return VM.isBooted() && StackStreamFactory.useNewThrowable;
+ }
+
+ /*
+ * This should only be used by Throwable::<init>.
+ */
+ static StackTrace makeStackTrace(Throwable ex) {
+ return StackTrace.dump(ex);
+ }
+
+ /*
+ * This creates StackTrace for Thread::dumpThread to use.
+ */
+ static StackTrace makeStackTrace() {
+ return StackTrace.dump();
+ }
+
+ enum WalkerState {
+ NEW, // the stream is new and stack walking has not started
+ OPEN, // the stream is open when it is being traversed.
+ CLOSED; // the stream is closed when the stack walking is done
+ }
+
+ static abstract class AbstractStackWalker<T> {
+ protected final StackWalker walker;
+ protected final Thread thread;
+ protected final int maxDepth;
+ protected final long mode;
+ protected int depth; // traversed stack depth
+ protected FrameBuffer frameBuffer; // buffer for VM to fill in
+ protected long anchor;
+
+ // buffers to fill in stack frame information
+ protected AbstractStackWalker(StackWalker walker, int mode) {
+ this(walker, mode, Integer.MAX_VALUE);
+ }
+ protected AbstractStackWalker(StackWalker walker, int mode, int maxDepth) {
+ this.thread = Thread.currentThread();
+ this.mode = toStackWalkMode(walker, mode);
+ this.walker = walker;
+ this.maxDepth = maxDepth;
+ this.depth = 0;
+ }
+
+ private int toStackWalkMode(StackWalker walker, int mode) {
+ int newMode = mode;
+ if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
+ !fillCallerClassOnly(newMode) /* don't show hidden frames for getCallerClass */)
+ newMode |= SHOW_HIDDEN_FRAMES;
+ if (walker.hasLocalsOperandsOption())
+ newMode |= FILL_LIVE_STACK_FRAMES;
+ return newMode;
+ }
+
+ private boolean fillCallerClassOnly(int mode) {
+ return (mode|FILL_CLASS_REFS_ONLY) != FILL_CLASS_REFS_ONLY;
+ }
+ /**
+ * A callback method to consume the stack frames. This method is invoked
+ * once stack walking begins (i.e. it is only invoked when walkFrames is called).
+ *
+ * Each specialized AbstractStackWalker subclass implements the consumeFrames method
+ * to control the following:
+ * 1. fetch the subsequent batches of stack frames
+ * 2. reuse or expand the allocated buffers
+ * 3. create specialized StackFrame objects
+ *
+ * @return the number of consumed frames
+ */
+ protected abstract T consumeFrames();
+
+ /**
+ * Initialize FrameBuffer. Subclass should implement this method to
+ * create its custom frame buffers.
+ */
+ protected abstract void initFrameBuffer();
+
+ /**
+ * Returns the suggested next batch size.
+ *
+ * Subclass should override this method to change the batch size
+ *
+ * @param lastBatchFrameCount number of frames in the last batch; or zero
+ * @return suggested batch size
+ */
+ protected abstract int batchSize(int lastBatchFrameCount);
+
+ /*
+ * Returns the next batch size, always >= minimum batch size (32)
+ *
+ * Subclass may override this method if the minimum batch size is different.
+ */
+ protected int getNextBatchSize() {
+ int lastBatchSize = depth == 0 ? 0 : frameBuffer.curBatchFrameCount();
+ int nextBatchSize = batchSize(lastBatchSize);
+ if (isDebug) {
+ System.err.println("last batch size = " + lastBatchSize +
+ " next batch size = " + nextBatchSize);
+ }
+ return nextBatchSize >= MIN_BATCH_SIZE ? nextBatchSize : MIN_BATCH_SIZE;
+ }
+
+ /*
+ * Checks if this stream is in the given state. Otherwise, throws IllegalStateException.
+ *
+ * VM also validates this stream if it's anchored for stack walking
+ * when stack frames are fetched for each batch.
+ */
+ final void checkState(WalkerState state) {
+ if (thread != Thread.currentThread()) {
+ throw new IllegalStateException("Invalid thread walking this stack stream: " +
+ Thread.currentThread().getName() + " " + thread.getName());
+ }
+ switch (state) {
+ case NEW:
+ if (anchor != 0) {
+ throw new IllegalStateException("This stack stream is being reused.");
+ }
+ break;
+ case OPEN:
+ if (anchor == 0 || anchor == -1L) {
+ throw new IllegalStateException("This stack stream is not valid for walking.");
+ }
+ break;
+ case CLOSED:
+ if (anchor != -1L) {
+ throw new IllegalStateException("This stack stream is not closed.");
+ }
+ }
+ }
+
+ /*
+ * Close this stream. This stream becomes invalid to walk.
+ */
+ private void close() {
+ this.anchor = -1L;
+ }
+
+ /*
+ * Walks stack frames until {@link #consumeFrames} is done consuming
+ * the frames it is interested in.
+ */
+ final T walk() {
+ checkState(NEW);
+ try {
+ // VM will need to stablize the stack before walking. It will invoke
+ // the AbstractStackWalker::doStackWalk method once it fetches the first batch.
+ // the callback will be invoked within the scope of the callStackWalk frame.
+ return beginStackWalk();
+ } finally {
+ close(); // done traversal; close the stream
+ }
+ }
+
+ private boolean skipReflectionFrames() {
+ return !walker.hasOption(Option.SHOW_REFLECT_FRAMES) &&
+ !walker.hasOption(Option.SHOW_HIDDEN_FRAMES);
+ }
+
+ /*
+ * Returns {@code Class} object at the current frame;
+ * or {@code null} if no more frame. If advanceToNextBatch is true,
+ * it will only fetch the next batch.
+ */
+ final Class<?> peekFrame() {
+ while (frameBuffer.isActive() && depth < maxDepth) {
+ if (frameBuffer.isEmpty()) {
+ // fetch another batch of stack frames
+ getNextBatch();
+ } else {
+ Class<?> c = frameBuffer.get();
+ if (skipReflectionFrames() && isReflectionFrame(c)) {
+ if (isDebug)
+ System.err.println(" skip: frame " + frameBuffer.getIndex() + " " + c);
+
+ frameBuffer.next();
+ depth++;
+ continue;
+ } else {
+ return c;
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * This method is only invoked by VM.
+ *
+ * It will invoke the consumeFrames method to start the stack walking
+ * with the first batch of stack frames. Each specialized AbstractStackWalker
+ * subclass implements the consumeFrames method to control the following:
+ * 1. fetch the subsequent batches of stack frames
+ * 2. reuse or expand the allocated buffers
+ * 3. create specialized StackFrame objects
+ */
+ private Object doStackWalk(long anchor, int skipFrames, int batchSize,
+ int bufStartIndex, int bufEndIndex) {
+ checkState(NEW);
+
+ frameBuffer.check(skipFrames);
+
+ if (isDebug) {
+ System.err.format("doStackWalk: skip %d start %d end %d%n",
+ skipFrames, bufStartIndex, bufEndIndex);
+ }
+
+ this.anchor = anchor; // set anchor for this bulk stack frame traversal
+ frameBuffer.setBatch(bufStartIndex, bufEndIndex);
+
+ // traverse all frames and perform the action on the stack frames, if specified
+ return consumeFrames();
+ }
+
+ /*
+ * Get next batch of stack frames.
+ */
+ private int getNextBatch() {
+ int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize());
+ if (!frameBuffer.isActive() || nextBatchSize <= 0) {
+ if (isDebug) {
+ System.out.format(" more stack walk done%n");
+ }
+ frameBuffer.freeze(); // stack walk done
+ return 0;
+ }
+
+ return fetchStackFrames(nextBatchSize);
+ }
+
+ /*
+ * This method traverses the next stack frame and returns the Class
+ * invoking that stack frame.
+ *
+ * This method can only be called during the walk method. This is intended
+ * to be used to walk the stack frames in one single invocation and
+ * this stack stream will be invalidated once walk is done.
+ *
+ * @see #tryNextFrame
+ */
+ final Class<?> nextFrame() {
+ if (!hasNext()) {
+ return null;
+ }
+
+ Class<?> c = frameBuffer.next();
+ depth++;
+ return c;
+ }
+
+ /*
+ * Returns true if there is next frame to be traversed.
+ * This skips hidden frames unless this StackWalker has
+ * {@link Option#SHOW_REFLECT_FRAMES}
+ */
+ final boolean hasNext() {
+ return peekFrame() != null;
+ }
+
+ /**
+ * Begin stack walking - pass the allocated arrays to the VM to fill in
+ * stack frame information.
+ *
+ * VM first anchors the frame of the current thread. A traversable stream
+ * on this thread's stack will be opened. The VM will fetch the first batch
+ * of stack frames and call AbstractStackWalker::doStackWalk to invoke the
+ * stack walking function on each stack frame.
+ *
+ * If all fetched stack frames are traversed, AbstractStackWalker::fetchStackFrames will
+ * fetch the next batch of stack frames to continue.
+ */
+ private T beginStackWalk() {
+ // initialize buffers for VM to fill the stack frame info
+ initFrameBuffer();
+
+ return callStackWalk(mode, 0,
+ frameBuffer.curBatchFrameCount(),
+ frameBuffer.startIndex(),
+ frameBuffer.classes,
+ frameBuffer.stackFrames);
+ }
+
+ /*
+ * Fetches stack frames.
+ *
+ * @params batchSize number of elements of the frame buffers for this batch
+ * @returns number of frames fetched in this batch
+ */
+ private int fetchStackFrames(int batchSize) {
+ int startIndex = frameBuffer.startIndex();
+ frameBuffer.resize(startIndex, batchSize);
+
+ int endIndex = fetchStackFrames(mode, anchor, batchSize,
+ startIndex,
+ frameBuffer.classes,
+ frameBuffer.stackFrames);
+ if (isDebug) {
+ System.out.format(" more stack walk requesting %d got %d to %d frames%n",
+ batchSize, frameBuffer.startIndex(), endIndex);
+ }
+ int numFrames = endIndex - startIndex;
+ if (numFrames == 0) {
+ frameBuffer.freeze(); // done stack walking
+ } else {
+ frameBuffer.setBatch(startIndex, endIndex);
+ }
+ return numFrames;
+ }
+
+ /**
+ * Begins stack walking. This method anchors this frame and invokes
+ * AbstractStackWalker::doStackWalk after fetching the firt batch of stack frames.
+ *
+ * @param mode mode of stack walking
+ * @param skipframes number of frames to be skipped before filling the frame buffer.
+ * @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
+ * @param startIndex start index of the frame buffers to be filled.
+ * @param classes Classes buffer of the stack frames
+ * @param frames StackFrame buffer, or null
+ * @return Result of AbstractStackWalker::doStackWalk
+ */
+ private native T callStackWalk(long mode, int skipframes,
+ int batchSize, int startIndex,
+ Class<?>[] classes,
+ StackFrame[] frames);
+
+ /**
+ * Fetch the next batch of stack frames.
+ *
+ * @param mode mode of stack walking
+ * @param anchor
+ * @param batchSize the batch size, max. number of elements to be filled in the frame buffers.
+ * @param startIndex start index of the frame buffers to be filled.
+ * @param classes Classes buffer of the stack frames
+ * @param frames StackFrame buffer, or null
+ *
+ * @return the end index to the frame buffers
+ */
+ private native int fetchStackFrames(long mode, long anchor,
+ int batchSize, int startIndex,
+ Class<?>[] classes,
+ StackFrame[] frames);
+
+
+ /*
+ * Frame buffer
+ *
+ * Each specialized AbstractStackWalker subclass may subclass the FrameBuffer.
+ */
+ class FrameBuffer {
+ static final int START_POS = 2; // 0th and 1st elements are reserved
+
+ // buffers for VM to fill stack frame info
+ int currentBatchSize; // current batch size
+ Class<?>[] classes; // caller class for fast path
+
+ StackFrame[] stackFrames;
+
+ int origin; // index to the current traversed stack frame
+ int fence; // index to the last frame in the current batch
+
+ FrameBuffer(int initialBatchSize) {
+ if (initialBatchSize < MIN_BATCH_SIZE) {
+ throw new IllegalArgumentException(initialBatchSize + " < minimum batch size: " + MIN_BATCH_SIZE);
+ }
+ this.origin = START_POS;
+ this.fence = 0;
+ this.currentBatchSize = initialBatchSize;
+ this.classes = new Class<?>[currentBatchSize];
+ }
+
+ int curBatchFrameCount() {
+ return currentBatchSize-START_POS;
+ }
+
+ /*
+ * Tests if this frame buffer is empty. All frames are fetched.
+ */
+ final boolean isEmpty() {
+ return origin >= fence || (origin == START_POS && fence == 0);
+ }
+
+ /*
+ * Freezes this frame buffer. The stack stream source is done fetching.
+ */
+ final void freeze() {
+ origin = 0;
+ fence = 0;
+ }
+
+ /*
+ * Tests if this frame buffer is active. It is inactive when
+ * it is done for traversal. All stack frames have been traversed.
+ */
+ final boolean isActive() {
+ return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize);
+ }
+
+ /**
+ * Gets the class at the current frame and move to the next frame.
+ */
+ final Class<?> next() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+ }
+ Class<?> c = classes[origin++];
+ if (isDebug) {
+ int index = origin-1;
+ System.out.format(" next frame at %d: %s (origin %d fence %d)%n", index,
+ Objects.toString(c), index, fence);
+ }
+ return c;
+ }
+
+ /**
+ * Gets the class at the current frame.
+ */
+ final Class<?> get() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+ }
+ return classes[origin];
+ }
+
+ /*
+ * Returns the index of the current frame.
+ */
+ final int getIndex() {
+ return origin;
+ }
+
+ /*
+ * Set the start and end index of a new batch of stack frames that have
+ * been filled in this frame buffer.
+ */
+ final void setBatch(int startIndex, int endIndex) {
+ if (startIndex <= 0 || endIndex <= 0)
+ throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+
+ this.origin = startIndex;
+ this.fence = endIndex;
+ if (depth == 0 && fence > 0) {
+ // filter the frames due to the stack stream implementation
+ for (int i = START_POS; i < fence; i++) {
+ Class<?> c = classes[i];
+ if (isDebug) System.err.format(" frame %d: %s%n", i, c);
+ if (filterStackWalkImpl(c)) {
+ origin++;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Checks if the origin is the expected start index.
+ */
+ final void check(int skipFrames) {
+ int index = skipFrames + START_POS;
+ if (origin != index) {
+ // stack walk must continue with the previous frame depth
+ throw new IllegalStateException("origin " + origin + " != " + index);
+ }
+ }
+
+ // ------ subclass may override the following methods -------
+ /**
+ * Resizes the buffers for VM to fill in the next batch of stack frames.
+ * The next batch will start at the given startIndex with the maximum number
+ * of elements.
+ *
+ * <p> Subclass may override this method to manage the allocated buffers.
+ *
+ * @param startIndex the start index for the first frame of the next batch to fill in.
+ * @param elements the number of elements for the next batch to fill in.
+ *
+ */
+ void resize(int startIndex, int elements) {
+ if (!isActive())
+ throw new IllegalStateException("inactive frame buffer can't be resized");
+
+ int size = startIndex+elements;
+ if (classes.length < size) {
+ // copy the elements in classes array to the newly allocated one.
+ // classes[0] is a Thread object
+ Class<?>[] prev = classes;
+ classes = new Class<?>[size];
+ System.arraycopy(prev, 0, classes, 0, START_POS);
+ }
+ currentBatchSize = size;
+ }
+
+ /*
+ * Returns the start index for this frame buffer is refilled.
+ *
+ * This implementation reuses the allocated buffer for the next batch
+ * of stack frames. For subclass to retain the fetched stack frames,
+ * it should override this method to return the index at which the frame
+ * should be filled in for the next batch.
+ */
+ int startIndex() {
+ return START_POS;
+ }
+
+ /**
+ * Returns next StackFrame object in the current batch of stack frames
+ */
+ StackFrame nextStackFrame() {
+ throw new InternalError("should not reach here");
+ }
+ }
+ }
+
+ /*
+ * This StackFrameTraverser supports {@link Stream} traversal.
+ *
+ * This class implements Spliterator::forEachRemaining and Spliterator::tryAdvance.
+ */
+ static class StackFrameTraverser<T> extends AbstractStackWalker<T>
+ implements Spliterator<StackFrame>
+ {
+ static {
+ stackWalkImplClasses.add(StackFrameTraverser.class);
+ }
+ private static final int CHARACTERISTICS = Spliterator.ORDERED | Spliterator.IMMUTABLE;
+ class Buffer extends FrameBuffer {
+ Buffer(int initialBatchSize) {
+ super(initialBatchSize);
+
+ this.stackFrames = new StackFrame[initialBatchSize];
+ for (int i = START_POS; i < initialBatchSize; i++) {
+ stackFrames[i] = new StackFrameInfo(walker);
+ }
+ }
+
+ @Override
+ void resize(int startIndex, int elements) {
+ super.resize(startIndex, elements);
+
+ int size = startIndex+elements;
+ if (stackFrames.length < size) {
+ stackFrames = new StackFrame[size];
+ }
+ for (int i = startIndex(); i < size; i++) {
+ stackFrames[i] = new StackFrameInfo(walker);
+ }
+ }
+
+ @Override
+ StackFrame nextStackFrame() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+ }
+
+ StackFrame frame = stackFrames[origin];
+ origin++;
+ return frame;
+ }
+ }
+
+ final Function<? super Stream<StackFrame>, ? extends T> function; // callback
+
+ StackFrameTraverser(StackWalker walker,
+ Function<? super Stream<StackFrame>, ? extends T> function) {
+ this(walker, function, DEFAULT_MODE);
+ }
+ StackFrameTraverser(StackWalker walker,
+ Function<? super Stream<StackFrame>, ? extends T> function,
+ int mode) {
+ super(walker, mode);
+ this.function = function;
+ }
+
+ /**
+ * Returns next StackFrame object in the current batch of stack frames;
+ * or null if no more stack frame.
+ */
+ StackFrame nextStackFrame() {
+ if (!hasNext()) {
+ return null;
+ }
+
+ StackFrame frame = frameBuffer.nextStackFrame();
+ depth++;
+ return frame;
+ }
+
+ @Override
+ protected T consumeFrames() {
+ checkState(OPEN);
+ Stream<StackFrame> stream = StreamSupport.stream(this, false);
+ if (function != null) {
+ return function.apply(stream);
+ } else
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void initFrameBuffer() {
+ this.frameBuffer = new Buffer(getNextBatchSize());
+ }
+
+ @Override
+ protected int batchSize(int lastBatchFrameCount) {
+ if (lastBatchFrameCount == 0) {
+ // First batch, use estimateDepth if not exceed the large batch size
+ // and not too small
+ int initialBatchSize = Math.max(walker.estimateDepth(), SMALL_BATCH);
+ return Math.min(initialBatchSize, LARGE_BATCH_SIZE);
+ } else {
+ if (lastBatchFrameCount > BATCH_SIZE) {
+ return lastBatchFrameCount;
+ } else {
+ return Math.min(lastBatchFrameCount*2, BATCH_SIZE);
+ }
+ }
+ }
+
+ // ------- Implementation of Spliterator
+
+ @Override
+ public Spliterator<StackFrame> trySplit() {
+ return null; // ordered stream and do not allow to split
+ }
+
+ @Override
+ public long estimateSize() {
+ return maxDepth;
+ }
+
+ @Override
+ public int characteristics() {
+ return CHARACTERISTICS;
+ }
+
+ @Override
+ public void forEachRemaining(Consumer<? super StackFrame> action) {
+ checkState(OPEN);
+ for (int n = 0; n < maxDepth; n++) {
+ StackFrame frame = nextStackFrame();
+ if (frame == null) break;
+
+ action.accept(frame);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(Consumer<? super StackFrame> action) {
+ checkState(OPEN);
+
+ int index = frameBuffer.getIndex();
+ if (hasNext()) {
+ StackFrame frame = nextStackFrame();
+ action.accept(frame);
+ if (isDebug) {
+ System.err.println("tryAdvance: " + index + " " + frame);
+ }
+ return true;
+ }
+ if (isDebug) {
+ System.err.println("tryAdvance: " + index + " NO element");
+ }
+ return false;
+ }
+ }
+
+ /*
+ * CallerClassFinder is specialized to return Class<?> for each stack frame.
+ * StackFrame is not requested.
+ */
+ static class CallerClassFinder extends AbstractStackWalker<Integer> {
+ static {
+ stackWalkImplClasses.add(CallerClassFinder.class);
+ }
+
+ private Class<?> caller;
+
+ CallerClassFinder(StackWalker walker) {
+ super(walker, FILL_CLASS_REFS_ONLY);
+ }
+
+ Class<?> findCaller() {
+ walk();
+ return caller;
+ }
+
+ @Override
+ protected Integer consumeFrames() {
+ checkState(OPEN);
+ int n = 0;
+ Class<?>[] frames = new Class<?>[2];
+ // skip the API calling this getCallerClass method
+ // 0: StackWalker::getCallerClass
+ // 1: caller-sensitive method
+ // 2: caller class
+ while (n < 2 && (caller = nextFrame()) != null) {
+ if (isMethodHandleFrame(caller)) continue;
+ frames[n++] = caller;
+ }
+
+ if (frames[1] == null)
+ throw new IllegalStateException("no caller frame");
+ return n;
+ }
+
+ @Override
+ protected void initFrameBuffer() {
+ this.frameBuffer = new FrameBuffer(getNextBatchSize());
+ }
+
+ @Override
+ protected int batchSize(int lastBatchFrameCount) {
+ return MIN_BATCH_SIZE;
+ }
+
+ @Override
+ protected int getNextBatchSize() {
+ return MIN_BATCH_SIZE;
+ }
+ }
+
+ /*
+ * StackTrace caches all frames in the buffer. StackTraceElements are
+ * created lazily when Throwable::getStackTrace is called.
+ */
+ static class StackTrace extends AbstractStackWalker<Integer> {
+ static {
+ stackWalkImplClasses.add(StackTrace.class);
+ }
+
+ class GrowableBuffer extends FrameBuffer {
+ GrowableBuffer(int initialBatchSize) {
+ super(initialBatchSize);
+
+ this.stackFrames = new StackFrame[initialBatchSize];
+ for (int i = START_POS; i < initialBatchSize; i++) {
+ stackFrames[i] = new StackFrameInfo(walker);
+ }
+ }
+
+ /*
+ * Returns the next index to fill
+ */
+ @Override
+ int startIndex() {
+ return origin;
+ }
+
+ /**
+ * Initialize the buffers for VM to fill in the stack frame information.
+ * The next batch will start at the given startIndex to
+ * the length of the buffer.
+ */
+ @Override
+ void resize(int startIndex, int elements) {
+ // Expand the frame buffer.
+ // Do not call super.resize that will reuse the filled elements
+ // in this frame buffer
+ int size = startIndex+elements;
+ if (classes.length < size) {
+ // resize the frame buffer
+ classes = Arrays.copyOf(classes, size);
+ stackFrames = Arrays.copyOf(stackFrames, size);
+ }
+ for (int i = startIndex; i < size; i++) {
+ stackFrames[i] = new StackFrameInfo(walker);
+ }
+ currentBatchSize = size;
+ }
+
+ StackTraceElement get(int index) {
+ return new StackTraceElement(classes[index].getName(), "unknown", null, -1);
+ }
+
+ /**
+ * Returns an array of StackTraceElement for all stack frames cached in
+ * this StackTrace object.
+ * <p>
+ * This method is intended for Throwable::getOurStackTrace use only.
+ */
+ StackTraceElement[] toStackTraceElements() {
+ int startIndex = START_POS;
+ for (int i = startIndex; i < classes.length; i++) {
+ if (classes[i] != null && filterStackWalkImpl(classes[i])) {
+ startIndex++;
+ } else {
+ break;
+ }
+ }
+
+ // VM fills in the method name, filename, line number info
+ StackFrameInfo.fillInStackFrames(0, stackFrames, startIndex, startIndex + depth);
+
+ StackTraceElement[] stes = new StackTraceElement[depth];
+ for (int i = startIndex, j = 0; i < classes.length && j < depth; i++, j++) {
+ if (isDebug) {
+ System.err.println("StackFrame: " + i + " " + stackFrames[i]);
+ }
+ stes[j] = stackFrames[i].toStackTraceElement();
+ }
+ return stes;
+ }
+ }
+
+ private static final int MAX_STACK_FRAMES = 1024;
+ private static final StackWalker STACKTRACE_WALKER =
+ StackWalker.newInstanceNoCheck(EnumSet.of(Option.SHOW_REFLECT_FRAMES));
+
+ private StackTraceElement[] stes;
+ static StackTrace dump() {
+ return new StackTrace();
+ }
+
+ static StackTrace dump(Throwable ex) {
+ return new StackTrace(ex);
+ }
+
+ private StackTrace() {
+ this(STACKTRACE_WALKER, DEFAULT_MODE);
+ }
+
+ /*
+ * Throwable::fillInStackTrace and <init> of Throwable and subclasses
+ * are filtered in the VM.
+ */
+ private StackTrace(Throwable ex) {
+ this(STACKTRACE_WALKER, FILTER_FILL_IN_STACKTRACE); // skip Throwable::init frames
+ if (isDebug) {
+ System.err.println("dump stack for " + ex.getClass().getName());
+ }
+ }
+
+ StackTrace(StackWalker walker, int mode) {
+ super(walker, mode, MAX_STACK_FRAMES);
+
+ // snapshot the stack trace
+ walk();
+ }
+
+ @Override
+ protected Integer consumeFrames() {
+ // traverse all frames and perform the action on the stack frames, if specified
+ int n = 0;
+ while (n < maxDepth && nextFrame() != null) {
+ n++;
+ }
+ return n;
+ }
+
+ @Override
+ protected void initFrameBuffer() {
+ this.frameBuffer = new GrowableBuffer(getNextBatchSize());
+ }
+
+ // TODO: implement better heuristic
+ @Override
+ protected int batchSize(int lastBatchFrameCount) {
+ // chunk size of VM backtrace is 32
+ return lastBatchFrameCount == 0 ? 32 : 32;
+ }
+
+ /**
+ * Returns an array of StackTraceElement for all stack frames cached in
+ * this StackTrace object.
+ * <p>
+ * This method is intended for Throwable::getOurStackTrace use only.
+ */
+ synchronized StackTraceElement[] getStackTraceElements() {
+ if (stes == null) {
+ stes = ((GrowableBuffer) frameBuffer).toStackTraceElements();
+ // release the frameBuffer memory
+ frameBuffer = null;
+ }
+ return stes;
+ }
+
+ /*
+ * Prints stack trace to the given PrintStream.
+ *
+ * Further implementation could skip creating StackTraceElement objects
+ * print directly to the PrintStream.
+ */
+ void printStackTrace(PrintStream s) {
+ StackTraceElement[] stes = getStackTraceElements();
+ synchronized (s) {
+ s.println("Stack trace");
+ for (StackTraceElement traceElement : stes)
+ s.println("\tat " + traceElement);
+ }
+ }
+ }
+
+ static class LiveStackInfoTraverser<T> extends StackFrameTraverser<T> {
+ static {
+ stackWalkImplClasses.add(LiveStackInfoTraverser.class);
+ }
+ // VM will fill in all method info and live stack info directly in StackFrameInfo
+ class Buffer extends FrameBuffer {
+ Buffer(int initialBatchSize) {
+ super(initialBatchSize);
+ this.stackFrames = new StackFrame[initialBatchSize];
+ for (int i = START_POS; i < initialBatchSize; i++) {
+ stackFrames[i] = new LiveStackFrameInfo(walker);
+ }
+ }
+
+ @Override
+ void resize(int startIndex, int elements) {
+ super.resize(startIndex, elements);
+ int size = startIndex + elements;
+
+ if (stackFrames.length < size) {
+ this.stackFrames = new StackFrame[size];
+ }
+
+ for (int i = startIndex(); i < size; i++) {
+ stackFrames[i] = new LiveStackFrameInfo(walker);
+ }
+ }
+
+ @Override
+ StackFrame nextStackFrame() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("origin=" + origin + " fence=" + fence);
+ }
+
+ StackFrame frame = stackFrames[origin];
+ origin++;
+ return frame;
+ }
+ }
+
+ LiveStackInfoTraverser(StackWalker walker,
+ Function<? super Stream<StackFrame>, ? extends T> function) {
+ super(walker, function, DEFAULT_MODE);
+ }
+
+ @Override
+ protected void initFrameBuffer() {
+ this.frameBuffer = new Buffer(getNextBatchSize());
+ }
+ }
+
+ private static native boolean checkStackWalkModes();
+
+ // avoid loading other subclasses as they may not be used
+ private static Set<Class<?>> init() {
+ if (!checkStackWalkModes()) {
+ throw new InternalError("StackWalker mode values do not match with JVM");
+ }
+
+ Set<Class<?>> classes = new HashSet<>();
+ classes.add(StackWalker.class);
+ classes.add(StackStreamFactory.class);
+ classes.add(AbstractStackWalker.class);
+ return classes;
+ }
+
+ private static boolean filterStackWalkImpl(Class<?> c) {
+ return stackWalkImplClasses.contains(c) ||
+ c.getName().startsWith("java.util.stream.");
+ }
+
+ // MethodHandle frames are not hidden and CallerClassFinder has
+ // to filter them out
+ private static boolean isMethodHandleFrame(Class<?> c) {
+ return c.getName().startsWith("java.lang.invoke.");
+ }
+
+ private static boolean isReflectionFrame(Class<?> c) {
+ if (c.getName().startsWith("sun.reflect") &&
+ !sun.reflect.MethodAccessor.class.isAssignableFrom(c)) {
+ throw new InternalError("Not sun.reflect.MethodAccessor: " + c.toString());
+ }
+ // ## should filter all @Hidden frames?
+ return c == Method.class ||
+ sun.reflect.MethodAccessor.class.isAssignableFrom(c) ||
+ c.getName().startsWith("java.lang.invoke.LambdaForm");
+ }
+
+ private static boolean getProperty(String key, boolean value) {
+ String s = AccessController.doPrivileged(new PrivilegedAction<>() {
+ @Override
+ public String run() {
+ return System.getProperty(key);
+ }
+ });
+ if (s != null) {
+ return Boolean.valueOf(s);
+ }
+ return value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,563 @@
+/*
+ * 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 java.lang;
+
+import sun.reflect.CallerSensitive;
+
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+/**
+ * A stack walker.
+ *
+ * <p> The {@link StackWalker#walk walk} method opens a sequential stream
+ * of {@link StackFrame StackFrame}s for the current thread and then applies
+ * the given function to walk the {@code StackFrame} stream.
+ * The stream reports stack frame elements in order, from the top most frame
+ * that represents the execution point at which the stack was generated to
+ * the bottom most frame.
+ * The {@code StackFrame} stream is closed when the {@code walk} method returns.
+ * If an attempt is made to reuse the closed stream,
+ * {@code IllegalStateException} will be thrown.
+ *
+ * <p> The {@linkplain Option <em>stack walking options</em>} of a
+ * {@code StackWalker} determines the information of
+ * {@link StackFrame StackFrame} objects to be returned.
+ * By default, stack frames of the reflection API and implementation
+ * classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
+ * and {@code StackFrame}s have the class name and method name
+ * available but not the {@link StackFrame#getDeclaringClass() Class reference}.
+ *
+ * <p> {@code StackWalker} is thread-safe. Multiple threads can share
+ * a single {@code StackWalker} object to traverse its own stack.
+ * A permission check is performed when a {@code StackWalker} is created,
+ * according to the options it requests.
+ * No further permission check is done at stack walking time.
+ *
+ * @apiNote
+ * Examples
+ *
+ * <p>1. To find the first caller filtering a known list of implementation class:
+ * <pre>{@code
+ * StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
+ * Optional<Class<?>> callerClass = walker.walk(s ->
+ * s.map(StackFrame::getDeclaringClass)
+ * .filter(interestingClasses::contains)
+ * .findFirst());
+ * }</pre>
+ *
+ * <p>2. To snapshot the top 10 stack frames of the current thread,
+ * <pre>{@code
+ * List<StackFrame> stack = StackWalker.getInstance().walk(s ->
+ * s.limit(10).collect(Collectors.toList()));
+ * }</pre>
+ *
+ * Unless otherwise noted, passing a {@code null} argument to a
+ * constructor or method in this {@code StackWalker} class
+ * will cause a {@link NullPointerException NullPointerException}
+ * to be thrown.
+ *
+ * @since 1.9
+ */
+public final class StackWalker {
+ /**
+ * A {@code StackFrame} object represents a method invocation returned by
+ * {@link StackWalker}.
+ *
+ * <p> The {@link #getDeclaringClass()} method may be unsupported as determined
+ * by the {@linkplain Option stack walking options} of a {@linkplain
+ * StackWalker stack walker}.
+ *
+ * @since 1.9
+ * @jvms 2.6
+ */
+ public static interface StackFrame {
+ /**
+ * Gets the <a href="ClassLoader.html#name">binary name</a>
+ * of the declaring class of the method represented by this stack frame.
+ *
+ * @return the binary name of the declaring class of the method
+ * represented by this stack frame
+ *
+ * @jls 13.1 The Form of a Binary
+ */
+ public String getClassName();
+
+ /**
+ * Gets the name of the method represented by this stack frame.
+ * @return the name of the method represented by this stack frame
+ */
+ public String getMethodName();
+
+ /**
+ * Gets the declaring {@code Class} for the method represented by
+ * this stack frame.
+ *
+ * @return the declaring {@code Class} of the method represented by
+ * this stack frame
+ *
+ * @throws UnsupportedOperationException if this {@code StackWalker}
+ * is not configured with {@link Option#RETAIN_CLASS_REFERENCE
+ * Option.RETAIN_CLASS_REFERENCE}.
+ */
+ public Class<?> getDeclaringClass();
+
+ /**
+ * Returns the name of the source file containing the execution point
+ * represented by this stack frame. Generally, this corresponds
+ * to the {@code SourceFile} attribute of the relevant {@code class}
+ * file as defined by <cite>The Java Virtual Machine Specification</cite>.
+ * In some systems, the name may refer to some source code unit
+ * other than a file, such as an entry in a source repository.
+ *
+ * @return the name of the file containing the execution point
+ * represented by this stack frame, or empty {@code Optional}
+ * is unavailable.
+ *
+ * @jvms 4.7.10 The {@code SourceFile} Attribute
+ */
+ public Optional<String> getFileName();
+
+ /**
+ * Returns the line number of the source line containing the execution
+ * point represented by this stack frame. Generally, this is
+ * derived from the {@code LineNumberTable} attribute of the relevant
+ * {@code class} file as defined by <cite>The Java Virtual Machine
+ * Specification</cite>.
+ *
+ * @return the line number of the source line containing the execution
+ * point represented by this stack frame, or empty
+ * {@code Optional} if this information is unavailable.
+ *
+ * @jvms 4.7.12 The {@code LineNumberTable} Attribute
+ */
+ public OptionalInt getLineNumber();
+
+ /**
+ * Returns {@code true} if the method containing the execution point
+ * represented by this stack frame is a native method.
+ *
+ * @return {@code true} if the method containing the execution point
+ * represented by this stack frame is a native method.
+ */
+ public boolean isNativeMethod();
+
+ /**
+ * Gets a {@code StackTraceElement} for this stack frame.
+ *
+ * @return {@code StackTraceElement} for this stack frame.
+ *
+ * */
+ public default StackTraceElement toStackTraceElement() {
+ int lineNumber = isNativeMethod() ? -2
+ : getLineNumber().orElse(-1);
+ return new StackTraceElement(getClassName(), getMethodName(),
+ getFileName().orElse(null),
+ lineNumber);
+ }
+ }
+
+ /**
+ * Stack walker option to configure the {@linkplain StackFrame stack frame}
+ * information obtained by a {@code StackWalker}.
+ *
+ * @since 1.9
+ */
+ public enum Option {
+ /**
+ * Retains {@code Class} object in {@code StackFrame}s
+ * walked by this {@code StackWalker}.
+ *
+ * <p> A {@code StackWalker} configured with this option will support
+ * {@link StackWalker#getCallerClass()} and
+ * {@link StackFrame#getDeclaringClass() StackFrame.getDeclaringClass()}.
+ */
+ RETAIN_CLASS_REFERENCE,
+ /**
+ * Shows all reflection frames.
+ *
+ * <p>By default, reflection frames are hidden. This includes the
+ * {@link java.lang.reflect.Method#invoke} method
+ * and the reflection implementation classes. A {@code StackWalker} with
+ * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames.
+ * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
+ * reflection frames and it will also show other hidden frames that
+ * are implementation-specific.
+ */
+ SHOW_REFLECT_FRAMES,
+ /**
+ * Shows all hidden frames.
+ *
+ * <p>A Java Virtual Machine implementation may hide implementation
+ * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
+ * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
+ * option will show all hidden frames (including reflection frames).
+ */
+ SHOW_HIDDEN_FRAMES;
+ }
+
+ enum ExtendedOption {
+ /**
+ * Obtain monitors, locals and operands.
+ */
+ LOCALS_AND_OPERANDS
+ };
+
+ static final EnumSet<Option> DEFAULT_EMPTY_OPTION = EnumSet.noneOf(Option.class);
+
+ private final static StackWalker DEFAULT_WALKER =
+ new StackWalker(DEFAULT_EMPTY_OPTION);
+
+ private final Set<Option> options;
+ private final ExtendedOption extendedOption;
+ private final int estimateDepth;
+
+ /**
+ * Returns a {@code StackWalker} instance.
+ *
+ * <p> This {@code StackWalker} is configured to skip all
+ * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
+ * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+ *
+ * @return a {@code StackWalker} configured to skip all
+ * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
+ * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+ *
+ */
+ public static StackWalker getInstance() {
+ // no permission check needed
+ return DEFAULT_WALKER;
+ }
+
+ /**
+ * Returns a {@code StackWalker} instance with the given option specifying
+ * the stack frame information it can access.
+ *
+ * <p>
+ * If a security manager is present and the given {@code option} is
+ * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
+ * it calls its {@link SecurityManager#checkPermission checkPermission}
+ * method for {@code StackFramePermission("retainClassReference")}.
+ *
+ * @param option {@link Option stack walking option}
+ *
+ * @return a {@code StackWalker} configured with the given option
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkPermission} method denies access.
+ */
+ public static StackWalker getInstance(Option option) {
+ return getInstance(EnumSet.of(Objects.requireNonNull(option)));
+ }
+
+ /**
+ * Returns a {@code StackWalker} instance with the given {@code options} specifying
+ * the stack frame information it can access. If the given {@code options}
+ * is empty, this {@code StackWalker} is configured to skip all
+ * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
+ * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+ *
+ * <p>
+ * If a security manager is present and the given {@code options} contains
+ * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
+ * it calls its {@link SecurityManager#checkPermission checkPermission}
+ * method for {@code StackFramePermission("retainClassReference")}.
+ *
+ * @param options {@link Option stack walking option}
+ *
+ * @return a {@code StackWalker} configured with the given options
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkPermission} method denies access.
+ */
+ public static StackWalker getInstance(Set<Option> options) {
+ if (options.isEmpty()) {
+ return DEFAULT_WALKER;
+ }
+
+ checkPermission(options);
+ return new StackWalker(toEnumSet(options));
+ }
+
+ /**
+ * Returns a {@code StackWalker} instance with the given {@ocde options} specifying
+ * the stack frame information it can access. If the given {@ocde options}
+ * is empty, this {@code StackWalker} is configured to skip all
+ * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
+ * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+ *
+ * <p>
+ * If a security manager is present and the given {@code options} contains
+ * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
+ * it calls its {@link SecurityManager#checkPermission checkPermission}
+ * method for {@code StackFramePermission("retainClassReference")}.
+ *
+ * <p>
+ * The {@code estimateDepth} specifies the estimate number of stack frames
+ * this {@code StackWalker} will traverse that the {@code StackWalker} could
+ * use as a hint for the buffer size.
+ *
+ * @param options {@link Option stack walking options}
+ * @param estimateDepth Estimate number of stack frames to be traversed.
+ *
+ * @return a {@code StackWalker} configured with the given options
+ *
+ * @throws IllegalArgumentException if {@code estimateDepth <= 0}
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkPermission} method denies access.
+ */
+ public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
+ if (estimateDepth <= 0) {
+ throw new IllegalArgumentException("estimateDepth must be > 0");
+ }
+ checkPermission(options);
+ return new StackWalker(toEnumSet(options), estimateDepth);
+ }
+
+ // ----- private constructors ------
+ private StackWalker(EnumSet<Option> options) {
+ this(options, 0, null);
+ }
+ private StackWalker(EnumSet<Option> options, int estimateDepth) {
+ this(options, estimateDepth, null);
+ }
+ private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
+ this.options = options;
+ this.estimateDepth = estimateDepth;
+ this.extendedOption = extendedOption;
+ }
+
+ private static void checkPermission(Set<Option> options) {
+ Objects.requireNonNull(options);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
+ sm.checkPermission(new StackFramePermission("retainClassReference"));
+ }
+ }
+ }
+
+ /*
+ * Returns a defensive copy
+ */
+ private static EnumSet<Option> toEnumSet(Set<Option> options) {
+ Objects.requireNonNull(options);
+ if (options.isEmpty()) {
+ return DEFAULT_EMPTY_OPTION;
+ } else {
+ return EnumSet.copyOf(options);
+ }
+ }
+
+ /**
+ * Applies the given function to the stream of {@code StackFrame}s
+ * for the current thread, traversing from the top frame of the stack,
+ * which is the method calling this {@code walk} method.
+ *
+ * <p>The {@code StackFrame} stream will be closed when
+ * this method returns. When a closed {@code Stream<StackFrame>} object
+ * is reused, {@code IllegalStateException} will be thrown.
+ *
+ * @apiNote
+ * For example, to find the first 10 calling frames, first skipping those frames
+ * whose declaring class is in package {@code com.foo}:
+ * <blockquote>
+ * <pre>{@code
+ * List<StackFrame> frames = StackWalker.getInstance().walk(s ->
+ * s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
+ * .limit(10)
+ * .collect(Collectors.toList()));
+ * }</pre></blockquote>
+ *
+ * <p>This method takes a {@code Function} accepting a {@code Stream<StackFrame>},
+ * rather than returning a {@code Stream<StackFrame>} and allowing the
+ * caller to directly manipulate the stream. The Java virtual machine is
+ * free to reorganize a thread's control stack, for example, via
+ * deoptimization. By taking a {@code Function} parameter, this method
+ * allows access to stack frames through a stable view of a thread's control
+ * stack.
+ *
+ * <p>Parallel execution is effectively disabled and stream pipeline
+ * execution will only occur on the current thread.
+ *
+ * @implNote The implementation stabilizes the stack by anchoring a frame
+ * specific to the stack walking and ensures that the stack walking is
+ * performed above the anchored frame. When the stream object is closed or
+ * being reused, {@code IllegalStateException} will be thrown.
+ *
+ * @param function a function that takes a stream of
+ * {@linkplain StackFrame stack frames} and returns a result.
+ * @param <T> The type of the result of applying the function to the
+ * stream of {@linkplain StackFrame stack frame}.
+ *
+ * @return the result of applying the function to the stream of
+ * {@linkplain StackFrame stack frame}.
+ */
+ @CallerSensitive
+ public <T> T walk(Function<? super Stream<StackFrame>, ? extends T> function) {
+ // Returning a Stream<StackFrame> would be unsafe, as the stream could
+ // be used to access the stack frames in an uncontrolled manner. For
+ // example, a caller might pass a Spliterator of stack frames after one
+ // or more frames had been traversed. There is no robust way to detect
+ // whether the execution point when
+ // Spliterator.tryAdvance(java.util.function.Consumer<? super T>) is
+ // invoked is the exact same execution point where the stack frame
+ // traversal is expected to resume.
+
+ Objects.requireNonNull(function);
+ return StackStreamFactory.makeStackTraverser(this, function)
+ .walk();
+ }
+
+ /**
+ * Performs the given action on each element of {@code StackFrame} stream
+ * of the current thread, traversing from the top frame of the stack,
+ * which is the method calling this {@code forEach} method.
+ *
+ * <p> This method is equivalent to calling
+ * <blockquote>
+ * {@code walk(s -> { s.forEach(action); return null; });}
+ * </blockquote>
+ *
+ * @param action an action to be performed on each {@code StackFrame}
+ * of the stack of the current thread
+ */
+ @CallerSensitive
+ public void forEach(Consumer<? super StackFrame> action) {
+ Objects.requireNonNull(action);
+ StackStreamFactory.makeStackTraverser(this, s -> {
+ s.forEach(action);
+ return null;
+ }).walk();
+ }
+
+ /**
+ * Gets the {@code Class} object of the caller invoking the method
+ * that calls this {@code getCallerClass} method.
+ *
+ * <p> Reflection frames, {@link java.lang.invoke.MethodHandle} and
+ * hidden frames are filtered regardless of the
+ * {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
+ * and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
+ * this {@code StackWalker} has been configured.
+ *
+ * <p> This method throws {@code UnsupportedOperationException}
+ * if this {@code StackWalker} is not configured with
+ * {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option,
+ * This method should be called when a caller frame is present. If
+ * it is called from the last frame on the stack;
+ * {@code IllegalStateException} will be thrown.
+ *
+ * @apiNote
+ * For example, {@code Util::getResourceBundle} loads a resource bundle
+ * on behalf of the caller. It calls this {@code getCallerClass} method
+ * to find the method calling {@code Util::getResourceBundle} and use the caller's
+ * class loader to load the resource bundle. The caller class in this example
+ * is the {@code MyTool} class.
+ *
+ * <pre>{@code
+ * class Util {
+ * private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
+ * public ResourceBundle getResourceBundle(String bundleName) {
+ * Class<?> caller = walker.getCallerClass();
+ * return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader());
+ * }
+ * }
+ *
+ * class MyTool {
+ * private final Util util = new Util();
+ * private void init() {
+ * ResourceBundle rb = util.getResourceBundle("mybundle");
+ * }
+ * }
+ * }</pre>
+ *
+ * An equivalent way to find the caller class using the
+ * {@link StackWalker#walk walk} method is as follows
+ * (filtering the reflection frames, {@code MethodHandle} and hidden frames
+ * not shown below):
+ * <pre>{@code
+ * Optional<Class<?>> caller = walker.walk(s ->
+ * s.map(StackFrame::getDeclaringClass)
+ * .skip(2)
+ * .findFirst());
+ * }</pre>
+ *
+ * When the {@code getCallerClass} method is called from a method that
+ * is the last frame on the stack,
+ * for example, {@code static public void main} method launched by the
+ * {@code java} launcher or a method invoked from a JNI attached thread.
+ * {@code IllegalStateException} is thrown.
+ *
+ * @return {@code Class} object of the caller's caller invoking this method.
+ *
+ * @throws UnsupportedOperationException if this {@code StackWalker}
+ * is not configured with {@link Option#RETAIN_CLASS_REFERENCE
+ * Option.RETAIN_CLASS_REFERENCE}.
+ * @throws IllegalStateException if there is no caller frame, i.e.
+ * when this {@code getCallerClass} method is called from a method
+ * which is the last frame on the stack.
+ */
+ @CallerSensitive
+ public Class<?> getCallerClass() {
+ if (!options.contains(Option.RETAIN_CLASS_REFERENCE)) {
+ throw new UnsupportedOperationException("This stack walker " +
+ "does not have RETAIN_CLASS_REFERENCE access");
+ }
+
+ return StackStreamFactory.makeCallerFinder(this).findCaller();
+ }
+
+ // ---- package access ----
+ static StackWalker newInstanceNoCheck(EnumSet<Option> options) {
+ return new StackWalker(options, 0, null);
+ }
+
+ static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {
+ checkPermission(options);
+ return new StackWalker(toEnumSet(options), 0, extendedOption);
+ }
+
+ int estimateDepth() {
+ return estimateDepth;
+ }
+
+ boolean hasOption(Option option) {
+ return options.contains(option);
+ }
+
+ boolean hasLocalsOperandsOption() {
+ return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
+ }
+
+ void ensureAccessEnabled(Option access) {
+ if (!hasOption(access)) {
+ throw new UnsupportedOperationException("No access to " + access +
+ ": " + options.toString());
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Wed Dec 02 09:34:55 2015 -0800
@@ -730,7 +730,7 @@
count = fields.get("count", 0);
}
- protected synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
+ synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
super.getBytes(dst, dstBegin, coder);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/System.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Wed Dec 02 09:34:55 2015 -0800
@@ -1896,12 +1896,6 @@
public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
Shutdown.add(slot, registerShutdownInProgress, hook);
}
- public int getStackTraceDepth(Throwable t) {
- return t.getStackTraceDepth();
- }
- public StackTraceElement getStackTraceElement(Throwable t, int i) {
- return t.getStackTraceElement(i);
- }
public String newStringUnsafe(char[] chars) {
return new String(chars, true);
}
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Dec 02 09:34:55 2015 -0800
@@ -1329,11 +1329,9 @@
/**
* Prints a stack trace of the current thread to the standard error stream.
* This method is used only for debugging.
- *
- * @see Throwable#printStackTrace()
*/
public static void dumpStack() {
- new Exception("Stack trace").printStackTrace();
+ StackStreamFactory.makeStackTrace().printStackTrace(System.err);
}
/**
@@ -1556,7 +1554,7 @@
return stackTrace;
} else {
// Don't need JVM help for current thread
- return (new Exception()).getStackTrace();
+ return StackStreamFactory.makeStackTrace().getStackTraceElements();
}
}
@@ -2028,15 +2026,15 @@
// Hence, the fields are isolated with @Contended.
/** The current seed for a ThreadLocalRandom */
- @sun.misc.Contended("tlr")
+ @jdk.internal.vm.annotation.Contended("tlr")
long threadLocalRandomSeed;
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
- @sun.misc.Contended("tlr")
+ @jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomProbe;
/** Secondary seed isolated from public ThreadLocalRandom sequence */
- @sun.misc.Contended("tlr")
+ @jdk.internal.vm.annotation.Contended("tlr")
int threadLocalRandomSecondarySeed;
/* Some private helper methods */
--- a/jdk/src/java.base/share/classes/java/lang/Throwable.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java Wed Dec 02 09:34:55 2015 -0800
@@ -24,6 +24,8 @@
*/
package java.lang;
+import sun.misc.VM;
+
import java.io.*;
import java.util.*;
@@ -778,7 +780,11 @@
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
- fillInStackTrace(0);
+ if (backtrace == null && StackStreamFactory.useStackTrace(this)) {
+ backtrace = StackStreamFactory.makeStackTrace(this);
+ } else {
+ fillInStackTrace(0);
+ }
stackTrace = UNASSIGNED_STACK;
}
return this;
@@ -819,10 +825,14 @@
// backtrace if this is the first call to this method
if (stackTrace == UNASSIGNED_STACK ||
(stackTrace == null && backtrace != null) /* Out of protocol state */) {
- int depth = getStackTraceDepth();
- stackTrace = new StackTraceElement[depth];
- for (int i=0; i < depth; i++)
- stackTrace[i] = getStackTraceElement(i);
+ if (backtrace instanceof StackStreamFactory.StackTrace) {
+ stackTrace = ((StackStreamFactory.StackTrace)backtrace).getStackTraceElements();
+ } else {
+ int depth = getStackTraceDepth();
+ stackTrace = new StackTraceElement[depth];
+ for (int i = 0; i < depth; i++)
+ stackTrace[i] = getStackTraceElement(i);
+ }
} else if (stackTrace == null) {
return UNASSIGNED_STACK;
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Dec 02 09:34:55 2015 -0800
@@ -108,12 +108,6 @@
return makeAllocator(member);
return make(member.getDeclaringClass(), member);
}
- static DirectMethodHandle make(Method method) {
- return make(method.getDeclaringClass(), new MemberName(method));
- }
- static DirectMethodHandle make(Field field) {
- return make(field.getDeclaringClass(), new MemberName(field));
- }
private static DirectMethodHandle makeAllocator(MemberName ctor) {
assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
Class<?> instanceClass = ctor.getDeclaringClass();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Dec 02 09:34:55 2015 -0800
@@ -56,7 +56,6 @@
private static final String OBJ = "java/lang/Object";
private static final String OBJARY = "[Ljava/lang/Object;";
- private static final String MH_SIG = "L" + MH + ";";
private static final String LF_SIG = "L" + LF + ";";
private static final String LFN_SIG = "L" + LFN + ";";
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
@@ -77,7 +76,6 @@
/** Info about local variables in compiled lambda form */
private final int[] localsMap; // index
- private final BasicType[] localTypes; // basic type
private final Class<?>[] localClasses; // type
/** ASM bytecode generation. */
@@ -105,7 +103,6 @@
this.invokerType = invokerType;
this.localsMap = new int[localsMapSize+1];
// last entry of localsMap is count of allocated local slots
- this.localTypes = new BasicType[localsMapSize+1];
this.localClasses = new Class<?>[localsMapSize+1];
}
@@ -114,11 +111,8 @@
this(null, invokerType.parameterCount(),
className, invokerName, invokerType);
// Create an array to map name indexes to locals indexes.
- localTypes[localTypes.length - 1] = V_TYPE;
for (int i = 0; i < localsMap.length; i++) {
localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
- if (i < invokerType.parameterCount())
- localTypes[i] = basicType(invokerType.parameterType(i));
}
}
@@ -133,7 +127,6 @@
if (i < names.length) {
BasicType type = names[i].type();
index += type.basicTypeSlots();
- localTypes[i] = type;
}
}
}
@@ -461,31 +454,6 @@
return xas - Opcodes.AASTORE + aaop;
}
-
- private void freeFrameLocal(int oldFrameLocal) {
- int i = indexForFrameLocal(oldFrameLocal);
- if (i < 0) return;
- BasicType type = localTypes[i];
- int newFrameLocal = makeLocalTemp(type);
- mv.visitVarInsn(loadInsnOpcode(type), oldFrameLocal);
- mv.visitVarInsn(storeInsnOpcode(type), newFrameLocal);
- assert(localsMap[i] == oldFrameLocal);
- localsMap[i] = newFrameLocal;
- assert(indexForFrameLocal(oldFrameLocal) < 0);
- }
- private int indexForFrameLocal(int frameLocal) {
- for (int i = 0; i < localsMap.length; i++) {
- if (localsMap[i] == frameLocal && localTypes[i] != V_TYPE)
- return i;
- }
- return -1;
- }
- private int makeLocalTemp(BasicType type) {
- int frameLocal = localsMap[localsMap.length - 1];
- localsMap[localsMap.length - 1] = frameLocal + type.basicTypeSlots();
- return frameLocal;
- }
-
/**
* Emit a boxing call.
*
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Wed Dec 02 09:34:55 2015 -0800
@@ -197,17 +197,6 @@
if (!type.isPrimitive()) return L_TYPE;
return basicType(Wrapper.forPrimitiveType(type));
}
-
- static char basicTypeChar(Class<?> type) {
- return basicType(type).btChar;
- }
- static BasicType[] basicTypes(List<Class<?>> types) {
- BasicType[] btypes = new BasicType[types.size()];
- for (int i = 0; i < btypes.length; i++) {
- btypes[i] = basicType(types.get(i));
- }
- return btypes;
- }
static BasicType[] basicTypes(String types) {
BasicType[] btypes = new BasicType[types.length()];
for (int i = 0; i < btypes.length; i++) {
@@ -215,13 +204,19 @@
}
return btypes;
}
- static byte[] basicTypesOrd(BasicType[] btypes) {
- byte[] ords = new byte[btypes.length];
- for (int i = 0; i < btypes.length; i++) {
- ords[i] = (byte)btypes[i].ordinal();
+
+ static char basicTypeChar(Class<?> type) {
+ return basicType(type).btChar;
+ }
+
+ static byte[] basicTypesOrd(Class<?>[] types) {
+ byte[] ords = new byte[types.length];
+ for (int i = 0; i < ords.length; i++) {
+ ords[i] = (byte)basicType(types[i]).ordinal();
}
return ords;
}
+
static boolean isBasicTypeChar(char c) {
return "LIJFDV".indexOf(c) >= 0;
}
@@ -929,99 +924,6 @@
return false;
}
- LambdaForm addArguments(int pos, BasicType... types) {
- // names array has MH in slot 0; skip it.
- int argpos = pos + 1;
- assert(argpos <= arity);
- int length = names.length;
- int inTypes = types.length;
- Name[] names2 = Arrays.copyOf(names, length + inTypes);
- int arity2 = arity + inTypes;
- int result2 = result;
- if (result2 >= argpos)
- result2 += inTypes;
- // Note: The LF constructor will rename names2[argpos...].
- // Make space for new arguments (shift temporaries).
- System.arraycopy(names, argpos, names2, argpos + inTypes, length - argpos);
- for (int i = 0; i < inTypes; i++) {
- names2[argpos + i] = new Name(types[i]);
- }
- return new LambdaForm(debugName, arity2, names2, result2);
- }
-
- LambdaForm addArguments(int pos, List<Class<?>> types) {
- return addArguments(pos, basicTypes(types));
- }
-
- LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) {
- // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg.
- // The types are the types of the new (incoming) arguments.
- int length = names.length;
- int inTypes = types.length;
- int outArgs = reorder.length;
- assert(skip+outArgs == arity);
- assert(permutedTypesMatch(reorder, types, names, skip));
- int pos = 0;
- // skip trivial first part of reordering:
- while (pos < outArgs && reorder[pos] == pos) pos += 1;
- Name[] names2 = new Name[length - outArgs + inTypes];
- System.arraycopy(names, 0, names2, 0, skip+pos);
- // copy the body:
- int bodyLength = length - arity;
- System.arraycopy(names, skip+outArgs, names2, skip+inTypes, bodyLength);
- int arity2 = names2.length - bodyLength;
- int result2 = result;
- if (result2 >= 0) {
- if (result2 < skip+outArgs) {
- // return the corresponding inArg
- result2 = reorder[result2-skip];
- } else {
- result2 = result2 - outArgs + inTypes;
- }
- }
- // rework names in the body:
- for (int j = pos; j < outArgs; j++) {
- Name n = names[skip+j];
- int i = reorder[j];
- // replace names[skip+j] by names2[skip+i]
- Name n2 = names2[skip+i];
- if (n2 == null)
- names2[skip+i] = n2 = new Name(types[i]);
- else
- assert(n2.type == types[i]);
- for (int k = arity2; k < names2.length; k++) {
- names2[k] = names2[k].replaceName(n, n2);
- }
- }
- // some names are unused, but must be filled in
- for (int i = skip+pos; i < arity2; i++) {
- if (names2[i] == null)
- names2[i] = argument(i, types[i - skip]);
- }
- for (int j = arity; j < names.length; j++) {
- int i = j - arity + arity2;
- // replace names2[i] by names[j]
- Name n = names[j];
- Name n2 = names2[i];
- if (n != n2) {
- for (int k = i+1; k < names2.length; k++) {
- names2[k] = names2[k].replaceName(n, n2);
- }
- }
- }
- return new LambdaForm(debugName, arity2, names2, result2);
- }
-
- static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) {
- int inTypes = types.length;
- int outArgs = reorder.length;
- for (int i = 0; i < outArgs; i++) {
- assert(names[skip+i].isParam());
- assert(names[skip+i].type == types[reorder[i]]);
- }
- return true;
- }
-
static class NamedFunction {
final MemberName member;
private @Stable MethodHandle resolvedHandle;
@@ -1054,19 +956,15 @@
"invokeBasic".equals(member.getName());
}
- // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
+ // The next 2 constructors are used to break circular dependencies on MH.invokeStatic, etc.
// Any LambdaForm containing such a member is not interpretable.
// This is OK, since all such LFs are prepared with special primitive vmentry points.
// And even without the resolvedHandle, the name can still be compiled and optimized.
NamedFunction(Method method) {
this(new MemberName(method));
}
- NamedFunction(Field field) {
- this(new MemberName(field));
- }
NamedFunction(MemberName member) {
- this.member = member;
- this.resolvedHandle = null;
+ this(member, null);
}
MethodHandle resolvedHandle() {
@@ -1408,9 +1306,7 @@
}
Name(NamedFunction function, Object... arguments) {
this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class));
- assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
- for (int i = 0; i < arguments.length; i++)
- assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
+ assert(typesMatch(function, arguments));
}
/** Create a raw parameter of the given type, with an expected index. */
Name(int index, BasicType type) {
@@ -1550,7 +1446,15 @@
return buf.toString();
}
- static boolean typesMatch(BasicType parameterType, Object object) {
+ private boolean typesMatch(NamedFunction function, Object ... arguments) {
+ assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
+ for (int i = 0; i < arguments.length; i++) {
+ assert (typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
+ }
+ return true;
+ }
+
+ private static boolean typesMatch(BasicType parameterType, Object object) {
if (object instanceof Name) {
return ((Name)object).type == parameterType;
}
@@ -1630,7 +1534,7 @@
/** Return the number of times n is used as an argument or return value. */
int useCount(Name n) {
- int ni = n.index, nmax = names.length;
+ int nmax = names.length;
int end = lastUseIndex(n);
if (end < 0) return 0;
int count = 0;
@@ -1643,9 +1547,6 @@
return count;
}
- static Name argument(int which, char type) {
- return argument(which, basicType(type));
- }
static Name argument(int which, BasicType type) {
if (which >= INTERNED_ARGUMENT_LIMIT)
return new Name(which, type);
@@ -1661,28 +1562,7 @@
int length = types.length();
Name[] names = new Name[length + extra];
for (int i = 0; i < length; i++)
- names[i] = argument(i, types.charAt(i));
- return names;
- }
- static Name[] arguments(int extra, char... types) {
- int length = types.length;
- Name[] names = new Name[length + extra];
- for (int i = 0; i < length; i++)
- names[i] = argument(i, types[i]);
- return names;
- }
- static Name[] arguments(int extra, List<Class<?>> types) {
- int length = types.size();
- Name[] names = new Name[length + extra];
- for (int i = 0; i < length; i++)
- names[i] = argument(i, basicType(types.get(i)));
- return names;
- }
- static Name[] arguments(int extra, Class<?>... types) {
- int length = types.length;
- Name[] names = new Name[length + extra];
- for (int i = 0; i < length; i++)
- names[i] = argument(i, basicType(types[i]));
+ names[i] = argument(i, basicType(types.charAt(i)));
return names;
}
static Name[] arguments(int extra, MethodType types) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Wed Dec 02 09:34:55 2015 -0800
@@ -565,12 +565,12 @@
if (collectorArity == 1 && !dropResult) {
return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
}
- BasicType[] newTypes = BasicType.basicTypes(collectorType.parameterList());
+ byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
Transform.Kind kind = (dropResult
? Transform.Kind.COLLECT_ARGS_TO_VOID
: Transform.Kind.COLLECT_ARGS);
if (dropResult && collectorArity == 0) pos = 1; // pure side effect
- Transform key = Transform.of(kind, pos, collectorArity, BasicType.basicTypesOrd(newTypes));
+ Transform key = Transform.of(kind, pos, collectorArity, newTypes);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity - (dropResult ? 0 : 1) + collectorArity);
@@ -680,9 +680,8 @@
combinerArgs, 1, combinerArity);
} else {
newParams = new Name[combinerArity];
- BasicType[] newTypes = basicTypes(combinerType.parameterList());
- for (int i = 0; i < newTypes.length; i++) {
- newParams[i] = new Name(pos + i, newTypes[i]);
+ for (int i = 0; i < newParams.length; i++) {
+ newParams[i] = new Name(pos + i, basicType(combinerType.parameterType(i)));
}
System.arraycopy(newParams, 0,
combinerArgs, 1, combinerArity);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Wed Dec 02 09:34:55 2015 -0800
@@ -1077,4 +1077,13 @@
// System.out.println("Hello world! My methods are:");
// System.out.println(Factory.INSTANCE.getMethods(MemberName.class, true, null));
// }
+
+ static {
+ // Allow privileged classes outside of java.lang
+ jdk.internal.misc.SharedSecrets.setJavaLangInvokeAccess(new jdk.internal.misc.JavaLangInvokeAccess() {
+ public Object newMemberName() {
+ return new MemberName();
+ }
+ });
+ }
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Wed Dec 02 09:34:55 2015 -0800
@@ -938,7 +938,7 @@
Class<?> arrayElement = arrayType.getComponentType();
MethodType mtype = type();
boolean match = true, fail = false;
- for (int i = pos; i < arrayLength; i++) {
+ for (int i = pos; i < pos + arrayLength; i++) {
Class<?> ptype = mtype.parameterType(i);
if (ptype != arrayElement) {
match = false;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Dec 02 09:34:55 2015 -0800
@@ -92,33 +92,6 @@
TRACE_METHOD_LINKAGE);
}
- /*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
- if (type == null)
- type = target.type();
- MemberName name = null;
- if (target != null)
- name = target.internalMemberName();
- if (name == null)
- return "invoke" + type;
- return name.getName() + type;
- }
-
- /*non-public*/ static String getNameString(MethodHandle target, MethodHandle typeHolder) {
- return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type());
- }
-
- /*non-public*/ static String getNameString(MethodHandle target) {
- return getNameString(target, (MethodType) null);
- }
-
- /*non-public*/ static String addTypeString(Object obj, MethodHandle target) {
- String str = String.valueOf(obj);
- if (target == null) return str;
- int paren = str.indexOf('(');
- if (paren >= 0) str = str.substring(0, paren);
- return str + target.type();
- }
-
// handy shared exception makers (they simplify the common case code)
/*non-public*/ static InternalError newInternalError(String message) {
return new InternalError(message);
@@ -150,9 +123,6 @@
if (ex instanceof RuntimeException) throw (RuntimeException) ex;
throw newInternalError("uncaught exception", ex);
}
- static Error NYI() {
- throw new AssertionError("NYI");
- }
private static String message(String message, Object obj) {
if (obj != null) message = message + ": " + obj;
return message;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Wed Dec 02 09:34:55 2015 -0800
@@ -179,9 +179,11 @@
checkSlotCount(ptypes.length + slots);
return slots;
}
- static void checkSlotCount(int count) {
+ static {
+ // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
- // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
+ }
+ static void checkSlotCount(int count) {
if ((count & MAX_JVM_ARITY) != count)
throw newIllegalArgumentException("bad parameter count "+count);
}
@@ -813,11 +815,6 @@
boolean isViewableAs(MethodType newType, boolean keepInterfaces) {
if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces))
return false;
- return parametersAreViewableAs(newType, keepInterfaces);
- }
- /** True if the new parameters can be viewed (w/o casting) under the old parameter types. */
- /*non-public*/
- boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) {
if (form == newType.form && form.erasedType == this)
return true; // my reference parameters are all Object
if (ptypes == newType.ptypes)
@@ -1088,7 +1085,6 @@
throw newIllegalArgumentException("not a method descriptor: "+descriptor);
List<Class<?>> types = BytecodeDescriptor.parseMethod(descriptor, loader);
Class<?> rtype = types.remove(types.size() - 1);
- checkSlotCount(types.size());
Class<?>[] ptypes = listToArray(types);
return makeImpl(rtype, ptypes, true);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java Wed Dec 02 09:34:55 2015 -0800
@@ -52,7 +52,7 @@
private static final Wrapper[] FROM_WRAPPER_NAME = new Wrapper[16];
// Table of wrappers for primitives, indexed by ASM type sorts
- private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[16];
+ private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[12];
static {
for (Wrapper w : Wrapper.values()) {
@@ -63,11 +63,8 @@
}
}
- for (int i = 0; i < NUM_WRAPPERS; i++) {
- for (int j = 0; j < NUM_WRAPPERS; j++) {
- wideningOpcodes[i][j] = Opcodes.NOP;
- }
- }
+ // wideningOpcodes[][] will be NOP-initialized by default
+ assert(Opcodes.NOP == 0);
initWidening(LONG, Opcodes.I2L, BYTE, SHORT, INT, CHAR);
initWidening(LONG, Opcodes.F2L, FLOAT);
@@ -192,10 +189,6 @@
}
}
- private boolean isPrimitive(Wrapper w) {
- return w != OBJECT;
- }
-
private Wrapper toWrapper(String desc) {
char first = desc.charAt(0);
if (first == '[' || first == '(') {
--- a/jdk/src/java.base/share/classes/java/text/DateFormat.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/text/DateFormat.java Wed Dec 02 09:34:55 2015 -0800
@@ -418,7 +418,7 @@
* index information as described above.
* @return A <code>Date</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
--- a/jdk/src/java.base/share/classes/java/text/Format.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/text/Format.java Wed Dec 02 09:34:55 2015 -0800
@@ -225,7 +225,7 @@
* index information as described above.
* @return An <code>Object</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public abstract Object parseObject (String source, ParsePosition pos);
@@ -237,6 +237,7 @@
* @return An <code>Object</code> parsed from the string.
* @exception ParseException if the beginning of the specified string
* cannot be parsed.
+ * @throws NullPointerException if {@code source} is null.
*/
public Object parseObject(String source) throws ParseException {
ParsePosition pos = new ParsePosition(0);
--- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java Wed Dec 02 09:34:55 2015 -0800
@@ -1068,7 +1068,7 @@
* index information as described above.
* @return An <code>Object</code> array parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
--- a/jdk/src/java.base/share/classes/java/text/NumberFormat.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/text/NumberFormat.java Wed Dec 02 09:34:55 2015 -0800
@@ -271,7 +271,7 @@
* index information as described above.
* @return A <code>Number</code> parsed from the string. In case of
* error, returns null.
- * @exception NullPointerException if <code>pos</code> is null.
+ * @throws NullPointerException if {@code source} or {@code pos} is null.
*/
@Override
public final Object parseObject(String source, ParsePosition pos) {
--- a/jdk/src/java.base/share/classes/java/time/Clock.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/time/Clock.java Wed Dec 02 09:34:55 2015 -0800
@@ -223,6 +223,7 @@
*
* @param zone the time-zone to use to convert the instant to date-time, not null
* @return a clock that ticks in whole milliseconds using the specified zone, not null
+ * @since 9
*/
public static Clock tickMillis(ZoneId zone) {
return new TickClock(system(zone), NANOS_PER_MILLI);
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java Wed Dec 02 09:34:55 2015 -0800
@@ -307,6 +307,7 @@
* @param zone the time-zone, which may be an offset, not null
* @return the local date, not null
* @throws DateTimeException if the result exceeds the supported range
+ * @since 9
*/
public static LocalDate ofInstant(Instant instant, ZoneId zone) {
Objects.requireNonNull(instant, "instant");
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java Wed Dec 02 09:34:55 2015 -0800
@@ -354,6 +354,7 @@
* @param instant the instant to create the time from, not null
* @param zone the time-zone, which may be an offset, not null
* @return the local time, not null
+ * @since 9
*/
public static LocalTime ofInstant(Instant instant, ZoneId zone) {
Objects.requireNonNull(instant, "instant");
--- a/jdk/src/java.base/share/classes/java/util/Objects.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/Objects.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,6 +27,7 @@
import java.util.function.BiFunction;
import java.util.function.Supplier;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* This class consists of {@code static} utility methods for operating
@@ -420,14 +421,14 @@
* @throws IndexOutOfBoundsException if the {@code index} is out of bounds
* and the exception mapping function is {@code null}
* @since 9
- */
- /*
+ *
+ * @implNote
+ * This method is made intrinsic in optimizing compilers to guide
+ * them to perform unsigned comparisons of the index and length
+ * when it is known the length is a non-negative value (such as
+ * that of an array length or from the upper bound of a loop)
+ */
@HotSpotIntrinsicCandidate
- This method will be made intrinsic in C2 to guide HotSpot to perform
- unsigned comparisons of the index and length when it is known the length is
- a non-negative value (such as that of an array length or from the upper
- bound of a loop)
- */
public static <T extends RuntimeException>
int checkIndex(int index, int length,
BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Dec 02 09:34:55 2015 -0800
@@ -596,7 +596,16 @@
/** Number of CPUS, to place bounds on some sizings */
static final int NCPU = Runtime.getRuntime().availableProcessors();
- /** For serialization compatibility. */
+ /**
+ * Serialized pseudo-fields, provided only for jdk7 compatibility.
+ * @serialField segments Segment[]
+ * The segments, each of which is a specialized hash table.
+ * @serialField segmentMask int
+ * Mask value for indexing into segments. The upper bits of a
+ * key's hash code are used to choose the segment.
+ * @serialField segmentShift int
+ * Shift value for indexing within segments.
+ */
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("segments", Segment[].class),
new ObjectStreamField("segmentMask", Integer.TYPE),
@@ -1382,8 +1391,8 @@
* @param s the stream
* @throws java.io.IOException if an I/O error occurs
* @serialData
- * the key (Object) and value (Object)
- * for each key-value mapping, followed by a null pair.
+ * the serialized fields, followed by the key (Object) and value
+ * (Object) for each key-value mapping, followed by a null pair.
* The key-value mappings are emitted in no particular order.
*/
private void writeObject(java.io.ObjectOutputStream s)
@@ -1419,7 +1428,6 @@
}
s.writeObject(null);
s.writeObject(null);
- segments = null; // throw away
}
/**
@@ -2550,7 +2558,7 @@
* A padded cell for distributing counts. Adapted from LongAdder
* and Striped64. See their internal docs for explanation.
*/
- @sun.misc.Contended static final class CounterCell {
+ @jdk.internal.vm.annotation.Contended static final class CounterCell {
volatile long value;
CounterCell(long x) { value = x; }
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Wed Dec 02 09:34:55 2015 -0800
@@ -185,7 +185,7 @@
* }
* }}</pre>
*
- * As a further improvement, notice that the left task need not even exist.
+ * As a further optimization, notice that the left task need not even exist.
* Instead of creating a new one, we can iterate using the original task,
* and add a pending count for each fork. Additionally, because no task
* in this tree implements an {@link #onCompletion(CountedCompleter)} method,
@@ -208,7 +208,7 @@
* }
* }}</pre>
*
- * Additional improvements of such classes might entail precomputing
+ * Additional optimizations of such classes might entail precomputing
* pending counts so that they can be established in constructors,
* specializing classes for leaf steps, subdividing by say, four,
* instead of two per iteration, and using an adaptive threshold
@@ -260,9 +260,9 @@
* }}</pre>
*
* In this example, as well as others in which tasks have no other
- * effects except to compareAndSet a common result, the trailing
- * unconditional invocation of {@code tryComplete} could be made
- * conditional ({@code if (result.get() == null) tryComplete();})
+ * effects except to {@code compareAndSet} a common result, the
+ * trailing unconditional invocation of {@code tryComplete} could be
+ * made conditional ({@code if (result.get() == null) tryComplete();})
* because no further bookkeeping is required to manage completions
* once the root task completes.
*
@@ -624,7 +624,7 @@
* any one (versus all) of several subtask results are obtained.
* However, in the common (and recommended) case in which {@code
* setRawResult} is not overridden, this effect can be obtained
- * more simply using {@code quietlyCompleteRoot();}.
+ * more simply using {@link #quietlyCompleteRoot()}.
*
* @param rawResult the raw result
*/
@@ -639,9 +639,9 @@
/**
* If this task's pending count is zero, returns this task;
- * otherwise decrements its pending count and returns {@code
- * null}. This method is designed to be used with {@link
- * #nextComplete} in completion traversal loops.
+ * otherwise decrements its pending count and returns {@code null}.
+ * This method is designed to be used with {@link #nextComplete} in
+ * completion traversal loops.
*
* @return this task, if pending count was zero, else {@code null}
*/
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Wed Dec 02 09:34:55 2015 -0800
@@ -155,7 +155,7 @@
* a value that is enough for common platforms. Additionally,
* extra care elsewhere is taken to avoid other false/unintended
* sharing and to enhance locality, including adding padding (via
- * sun.misc.Contended) to Nodes, embedding "bound" as an Exchanger
+ * jdk.internal.vm.annotation.Contended) to Nodes, embedding "bound" as an Exchanger
* field, and reworking some park/unpark mechanics compared to
* LockSupport versions.
*
@@ -304,10 +304,10 @@
/**
* Nodes hold partially exchanged data, plus other per-thread
- * bookkeeping. Padded via @sun.misc.Contended to reduce memory
+ * bookkeeping. Padded via @jdk.internal.vm.annotation.Contended to reduce memory
* contention.
*/
- @sun.misc.Contended static final class Node {
+ @jdk.internal.vm.annotation.Contended static final class Node {
int index; // Arena index
int bound; // Last recorded value of Exchanger.bound
int collides; // Number of CAS failures at current bound
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Wed Dec 02 09:34:55 2015 -0800
@@ -162,7 +162,7 @@
* @since 1.7
* @author Doug Lea
*/
-@sun.misc.Contended
+@jdk.internal.vm.annotation.Contended
public class ForkJoinPool extends AbstractExecutorService {
/*
@@ -703,7 +703,8 @@
* Returns a new worker thread operating in the given pool.
*
* @param pool the pool this thread works in
- * @return the new worker thread
+ * @return the new worker thread, or {@code null} if the request
+ * to create a thread is rejected
* @throws NullPointerException if the pool is null
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
@@ -780,7 +781,7 @@
* arrays sharing cache lines. The @Contended annotation alerts
* JVMs to try to keep instances apart.
*/
- @sun.misc.Contended
+ @jdk.internal.vm.annotation.Contended
static final class WorkQueue {
/**
@@ -818,7 +819,7 @@
final ForkJoinWorkerThread owner; // owning thread or null if shared
volatile Thread parker; // == owner during call to park; else null
volatile ForkJoinTask<?> currentJoin; // task being joined in awaitJoin
- @sun.misc.Contended("group2") // separate from other fields
+ @jdk.internal.vm.annotation.Contended("group2") // separate from other fields
volatile ForkJoinTask<?> currentSteal; // nonnull when running some task
WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
@@ -1053,7 +1054,7 @@
}
/**
- * Shared version of pop.
+ * Shared version of tryUnpush.
*/
final boolean trySharedUnpush(ForkJoinTask<?> task) {
boolean popped = false;
@@ -1064,7 +1065,8 @@
ForkJoinTask<?> t = (ForkJoinTask<?>) U.getObject(a, offset);
if (t == task &&
U.compareAndSwapInt(this, QLOCK, 0, 1)) {
- if (U.compareAndSwapObject(a, offset, task, null)) {
+ if (top == s + 1 && array == a &&
+ U.compareAndSwapObject(a, offset, task, null)) {
popped = true;
top = s;
}
@@ -1250,12 +1252,14 @@
for (CountedCompleter<?> r = t;;) {
if (r == task) {
if ((mode & IS_OWNED) == 0) {
- boolean popped;
+ boolean popped = false;
if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
- if (popped =
+ if (top == s && array == a &&
U.compareAndSwapObject(a, offset,
- t, null))
+ t, null)) {
+ popped = true;
top = s - 1;
+ }
U.putOrderedInt(this, QLOCK, 0);
if (popped)
return t;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Wed Dec 02 09:34:55 2015 -0800
@@ -132,11 +132,10 @@
/*
* This class specializes ThreadPoolExecutor implementation by
*
- * 1. Using a custom task type, ScheduledFutureTask for
- * tasks, even those that don't require scheduling (i.e.,
- * those submitted using ExecutorService execute, not
- * ScheduledExecutorService methods) which are treated as
- * delayed tasks with a delay of zero.
+ * 1. Using a custom task type ScheduledFutureTask, even for tasks
+ * that don't require scheduling because they are submitted
+ * using ExecutorService rather than ScheduledExecutorService
+ * methods, which are treated as tasks with a delay of zero.
*
* 2. Using a custom queue (DelayedWorkQueue), a variant of
* unbounded DelayQueue. The lack of capacity constraint and
@@ -177,24 +176,17 @@
*/
private static final AtomicLong sequencer = new AtomicLong();
- /**
- * Returns current nanosecond time.
- */
- static final long now() {
- return System.nanoTime();
- }
-
private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {
/** Sequence number to break ties FIFO */
private final long sequenceNumber;
- /** The time the task is enabled to execute in nanoTime units */
+ /** The nanoTime-based time when the task is enabled to execute. */
private volatile long time;
/**
- * Period in nanoseconds for repeating tasks.
+ * Period for repeating tasks, in nanoseconds.
* A positive value indicates fixed-rate execution.
* A negative value indicates fixed-delay execution.
* A value of 0 indicates a non-repeating (one-shot) task.
@@ -244,7 +236,7 @@
}
public long getDelay(TimeUnit unit) {
- return unit.convert(time - now(), NANOSECONDS);
+ return unit.convert(time - System.nanoTime(), NANOSECONDS);
}
public int compareTo(Delayed other) {
@@ -287,6 +279,9 @@
}
public boolean cancel(boolean mayInterruptIfRunning) {
+ // The racy read of heapIndex below is benign:
+ // if heapIndex < 0, then OOTA guarantees that we have surely
+ // been removed; else we recheck under lock in remove()
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
@@ -528,7 +523,7 @@
* Returns the nanoTime-based trigger time of a delayed action.
*/
long triggerTime(long delay) {
- return now() +
+ return System.nanoTime() +
((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Wed Dec 02 09:34:55 2015 -0800
@@ -975,7 +975,7 @@
* than users expect.
*/
@SuppressWarnings("serial")
- @sun.misc.Contended
+ @jdk.internal.vm.annotation.Contended
private static final class BufferedSubscription<T>
implements Flow.Subscription, ForkJoinPool.ManagedBlocker {
// Order-sensitive field declarations
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Wed Dec 02 09:34:55 2015 -0800
@@ -365,12 +365,17 @@
/**
* Standard hotspot implementation using intrinsics.
*/
- private static class AtomicIntegerFieldUpdaterImpl<T>
- extends AtomicIntegerFieldUpdater<T> {
+ private static final class AtomicIntegerFieldUpdaterImpl<T>
+ extends AtomicIntegerFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
@@ -399,17 +404,15 @@
throw new RuntimeException(ex);
}
- Class<?> fieldt = field.getType();
- if (fieldt != int.class)
+ if (field.getType() != int.class)
throw new IllegalArgumentException("Must be integer type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
- this.cclass = (Modifier.isProtected(modifiers) &&
- caller != tclass) ? caller : null;
+ this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
- offset = U.objectFieldOffset(field);
+ this.offset = U.objectFieldOffset(field);
}
/**
@@ -428,81 +431,87 @@
return false;
}
- private void fullCheck(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(obj);
+ /**
+ * Checks that target argument is instance of cclass. On
+ * failure, throws cause.
+ */
+ private final void accessCheck(T obj) {
+ if (!cclass.isInstance(obj))
+ throwAccessCheckException(obj);
}
- public boolean compareAndSet(T obj, int expect, int update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ /**
+ * Throws access exception if accessCheck failed due to
+ * protected access, else ClassCastException.
+ */
+ private final void throwAccessCheckException(T obj) {
+ if (cclass == tclass)
+ throw new ClassCastException();
+ else
+ throw new RuntimeException(
+ new IllegalAccessException(
+ "Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()));
+ }
+
+ public final boolean compareAndSet(T obj, int expect, int update) {
+ accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
}
- public boolean weakCompareAndSet(T obj, int expect, int update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final boolean weakCompareAndSet(T obj, int expect, int update) {
+ accessCheck(obj);
return U.compareAndSwapInt(obj, offset, expect, update);
}
- public void set(T obj, int newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final void set(T obj, int newValue) {
+ accessCheck(obj);
U.putIntVolatile(obj, offset, newValue);
}
- public void lazySet(T obj, int newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final void lazySet(T obj, int newValue) {
+ accessCheck(obj);
U.putOrderedInt(obj, offset, newValue);
}
public final int get(T obj) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ accessCheck(obj);
return U.getIntVolatile(obj, offset);
}
- public int getAndSet(T obj, int newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final int getAndSet(T obj, int newValue) {
+ accessCheck(obj);
return U.getAndSetInt(obj, offset, newValue);
}
- public int getAndIncrement(T obj) {
- return getAndAdd(obj, 1);
- }
-
- public int getAndDecrement(T obj) {
- return getAndAdd(obj, -1);
- }
-
- public int getAndAdd(T obj, int delta) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final int getAndAdd(T obj, int delta) {
+ accessCheck(obj);
return U.getAndAddInt(obj, offset, delta);
}
- public int incrementAndGet(T obj) {
+ public final int getAndIncrement(T obj) {
+ return getAndAdd(obj, 1);
+ }
+
+ public final int getAndDecrement(T obj) {
+ return getAndAdd(obj, -1);
+ }
+
+ public final int incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
- public int decrementAndGet(T obj) {
+ public final int decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
- public int addAndGet(T obj, int delta) {
+ public final int addAndGet(T obj, int delta) {
return getAndAdd(obj, delta) + delta;
}
- private void ensureProtectedAccess(T obj) {
- if (cclass.isInstance(obj)) {
- return;
- }
- throw new RuntimeException(
- new IllegalAccessException("Class " +
- cclass.getName() +
- " can not access a protected member of class " +
- tclass.getName() +
- " using an instance of " +
- obj.getClass().getName()
- )
- );
- }
}
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Wed Dec 02 09:34:55 2015 -0800
@@ -365,11 +365,16 @@
return next;
}
- private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
CASUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@@ -397,103 +402,110 @@
throw new RuntimeException(ex);
}
- Class<?> fieldt = field.getType();
- if (fieldt != long.class)
+ if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
- this.cclass = (Modifier.isProtected(modifiers) &&
- caller != tclass) ? caller : null;
+ this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
- offset = U.objectFieldOffset(field);
+ this.offset = U.objectFieldOffset(field);
+ }
+
+ /**
+ * Checks that target argument is instance of cclass. On
+ * failure, throws cause.
+ */
+ private final void accessCheck(T obj) {
+ if (!cclass.isInstance(obj))
+ throwAccessCheckException(obj);
}
- private void fullCheck(T obj) {
- if (!tclass.isInstance(obj))
+ /**
+ * Throws access exception if accessCheck failed due to
+ * protected access, else ClassCastException.
+ */
+ private final void throwAccessCheckException(T obj) {
+ if (cclass == tclass)
throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(obj);
+ else
+ throw new RuntimeException(
+ new IllegalAccessException(
+ "Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()));
}
- public boolean compareAndSet(T obj, long expect, long update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final boolean compareAndSet(T obj, long expect, long update) {
+ accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
- public boolean weakCompareAndSet(T obj, long expect, long update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final boolean weakCompareAndSet(T obj, long expect, long update) {
+ accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
- public void set(T obj, long newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final void set(T obj, long newValue) {
+ accessCheck(obj);
U.putLongVolatile(obj, offset, newValue);
}
- public void lazySet(T obj, long newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final void lazySet(T obj, long newValue) {
+ accessCheck(obj);
U.putOrderedLong(obj, offset, newValue);
}
- public long get(T obj) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final long get(T obj) {
+ accessCheck(obj);
return U.getLongVolatile(obj, offset);
}
- public long getAndSet(T obj, long newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final long getAndSet(T obj, long newValue) {
+ accessCheck(obj);
return U.getAndSetLong(obj, offset, newValue);
}
- public long getAndIncrement(T obj) {
+ public final long getAndAdd(T obj, long delta) {
+ accessCheck(obj);
+ return U.getAndAddLong(obj, offset, delta);
+ }
+
+ public final long getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
- public long getAndDecrement(T obj) {
+ public final long getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
- public long getAndAdd(T obj, long delta) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
- return U.getAndAddLong(obj, offset, delta);
- }
-
- public long incrementAndGet(T obj) {
+ public final long incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
- public long decrementAndGet(T obj) {
+ public final long decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
- public long addAndGet(T obj, long delta) {
+ public final long addAndGet(T obj, long delta) {
return getAndAdd(obj, delta) + delta;
}
-
- private void ensureProtectedAccess(T obj) {
- if (cclass.isInstance(obj)) {
- return;
- }
- throw new RuntimeException(
- new IllegalAccessException("Class " +
- cclass.getName() +
- " can not access a protected member of class " +
- tclass.getName() +
- " using an instance of " +
- obj.getClass().getName()
- )
- );
- }
}
-
- private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
+ private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
- private final Class<?> cclass;
LockedUpdater(final Class<T> tclass, final String fieldName,
final Class<?> caller) {
@@ -521,28 +533,46 @@
throw new RuntimeException(ex);
}
- Class<?> fieldt = field.getType();
- if (fieldt != long.class)
+ if (field.getType() != long.class)
throw new IllegalArgumentException("Must be long type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
- this.cclass = (Modifier.isProtected(modifiers) &&
- caller != tclass) ? caller : null;
+ this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
- offset = U.objectFieldOffset(field);
+ this.offset = U.objectFieldOffset(field);
+ }
+
+ /**
+ * Checks that target argument is instance of cclass. On
+ * failure, throws cause.
+ */
+ private final void accessCheck(T obj) {
+ if (!cclass.isInstance(obj))
+ throw accessCheckException(obj);
}
- private void fullCheck(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(obj);
+ /**
+ * Returns access exception if accessCheck failed due to
+ * protected access, else ClassCastException.
+ */
+ private final RuntimeException accessCheckException(T obj) {
+ if (cclass == tclass)
+ return new ClassCastException();
+ else
+ return new RuntimeException(
+ new IllegalAccessException(
+ "Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()));
}
- public boolean compareAndSet(T obj, long expect, long update) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final boolean compareAndSet(T obj, long expect, long update) {
+ accessCheck(obj);
synchronized (this) {
long v = U.getLong(obj, offset);
if (v != expect)
@@ -552,42 +582,27 @@
}
}
- public boolean weakCompareAndSet(T obj, long expect, long update) {
+ public final boolean weakCompareAndSet(T obj, long expect, long update) {
return compareAndSet(obj, expect, update);
}
- public void set(T obj, long newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final void set(T obj, long newValue) {
+ accessCheck(obj);
synchronized (this) {
U.putLong(obj, offset, newValue);
}
}
- public void lazySet(T obj, long newValue) {
+ public final void lazySet(T obj, long newValue) {
set(obj, newValue);
}
- public long get(T obj) {
- if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+ public final long get(T obj) {
+ accessCheck(obj);
synchronized (this) {
return U.getLong(obj, offset);
}
}
-
- private void ensureProtectedAccess(T obj) {
- if (cclass.isInstance(obj)) {
- return;
- }
- throw new RuntimeException(
- new IllegalAccessException("Class " +
- cclass.getName() +
- " can not access a protected member of class " +
- tclass.getName() +
- " using an instance of " +
- obj.getClass().getName()
- )
- );
- }
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Dec 02 09:34:55 2015 -0800
@@ -286,9 +286,15 @@
extends AtomicReferenceFieldUpdater<T,V> {
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
+ /**
+ * if field is protected, the subclass constructing updater, else
+ * the same as tclass
+ */
+ private final Class<?> cclass;
+ /** class holding the field */
private final Class<T> tclass;
+ /** field value type */
private final Class<V> vclass;
- private final Class<?> cclass;
/*
* Internal type checks within all update methods contain
@@ -340,14 +346,10 @@
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
- this.cclass = (Modifier.isProtected(modifiers) &&
- caller != tclass) ? caller : null;
+ this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass;
this.tclass = tclass;
- if (vclass == Object.class)
- this.vclass = null;
- else
- this.vclass = vclass;
- offset = U.objectFieldOffset(field);
+ this.vclass = vclass;
+ this.offset = U.objectFieldOffset(field);
}
/**
@@ -366,83 +368,78 @@
return false;
}
- void targetCheck(T obj) {
- if (!tclass.isInstance(obj))
- throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(obj);
+ /**
+ * Checks that target argument is instance of cclass. On
+ * failure, throws cause.
+ */
+ private final void accessCheck(T obj) {
+ if (!cclass.isInstance(obj))
+ throwAccessCheckException(obj);
}
- void updateCheck(T obj, V update) {
- if (!tclass.isInstance(obj) ||
- (update != null && vclass != null && !vclass.isInstance(update)))
+ /**
+ * Throws access exception if accessCheck failed due to
+ * protected access, else ClassCastException.
+ */
+ private final void throwAccessCheckException(T obj) {
+ if (cclass == tclass)
throw new ClassCastException();
- if (cclass != null)
- ensureProtectedAccess(obj);
+ else
+ throw new RuntimeException(
+ new IllegalAccessException(
+ "Class " +
+ cclass.getName() +
+ " can not access a protected member of class " +
+ tclass.getName() +
+ " using an instance of " +
+ obj.getClass().getName()));
}
- public boolean compareAndSet(T obj, V expect, V update) {
- if (obj == null || obj.getClass() != tclass || cclass != null ||
- (update != null && vclass != null &&
- vclass != update.getClass()))
- updateCheck(obj, update);
+ private final void valueCheck(V v) {
+ if (v != null && !(vclass.isInstance(v)))
+ throwCCE();
+ }
+
+ static void throwCCE() {
+ throw new ClassCastException();
+ }
+
+ public final boolean compareAndSet(T obj, V expect, V update) {
+ accessCheck(obj);
+ valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
- public boolean weakCompareAndSet(T obj, V expect, V update) {
+ public final boolean weakCompareAndSet(T obj, V expect, V update) {
// same implementation as strong form for now
- if (obj == null || obj.getClass() != tclass || cclass != null ||
- (update != null && vclass != null &&
- vclass != update.getClass()))
- updateCheck(obj, update);
+ accessCheck(obj);
+ valueCheck(update);
return U.compareAndSwapObject(obj, offset, expect, update);
}
- public void set(T obj, V newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null ||
- (newValue != null && vclass != null &&
- vclass != newValue.getClass()))
- updateCheck(obj, newValue);
+ public final void set(T obj, V newValue) {
+ accessCheck(obj);
+ valueCheck(newValue);
U.putObjectVolatile(obj, offset, newValue);
}
- public void lazySet(T obj, V newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null ||
- (newValue != null && vclass != null &&
- vclass != newValue.getClass()))
- updateCheck(obj, newValue);
+ public final void lazySet(T obj, V newValue) {
+ accessCheck(obj);
+ valueCheck(newValue);
U.putOrderedObject(obj, offset, newValue);
}
@SuppressWarnings("unchecked")
- public V get(T obj) {
- if (obj == null || obj.getClass() != tclass || cclass != null)
- targetCheck(obj);
+ public final V get(T obj) {
+ accessCheck(obj);
return (V)U.getObjectVolatile(obj, offset);
}
@SuppressWarnings("unchecked")
- public V getAndSet(T obj, V newValue) {
- if (obj == null || obj.getClass() != tclass || cclass != null ||
- (newValue != null && vclass != null &&
- vclass != newValue.getClass()))
- updateCheck(obj, newValue);
+ public final V getAndSet(T obj, V newValue) {
+ accessCheck(obj);
+ valueCheck(newValue);
return (V)U.getAndSetObject(obj, offset, newValue);
}
-
- private void ensureProtectedAccess(T obj) {
- if (cclass.isInstance(obj)) {
- return;
- }
- throw new RuntimeException(
- new IllegalAccessException("Class " +
- cclass.getName() +
- " can not access a protected member of class " +
- tclass.getName() +
- " using an instance of " +
- obj.getClass().getName()
- )
- );
- }
}
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Wed Dec 02 09:34:55 2015 -0800
@@ -55,7 +55,7 @@
* accessed directly by subclasses.
*
* Table entries are of class Cell; a variant of AtomicLong padded
- * (via @sun.misc.Contended) to reduce cache contention. Padding
+ * (via @jdk.internal.vm.annotation.Contended) to reduce cache contention. Padding
* is overkill for most Atomics because they are usually
* irregularly scattered in memory and thus don't interfere much
* with each other. But Atomic objects residing in arrays will
@@ -119,7 +119,7 @@
* JVM intrinsics note: It would be possible to use a release-only
* form of CAS here, if it were provided.
*/
- @sun.misc.Contended static final class Cell {
+ @jdk.internal.vm.annotation.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
final boolean cas(long cmp, long val) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Wed Dec 02 09:34:55 2015 -0800
@@ -922,7 +922,7 @@
/**
* Queries whether any threads have ever contended to acquire this
- * synchronizer; that is if an acquire method has ever blocked.
+ * synchronizer; that is, if an acquire method has ever blocked.
*
* <p>In this implementation, this operation returns in
* constant time.
@@ -977,13 +977,11 @@
* guaranteeing termination.
*/
- Node t = tail;
Thread firstThread = null;
- while (t != null && t != head) {
- Thread tt = t.thread;
- if (tt != null)
- firstThread = tt;
- t = t.prev;
+ for (Node p = tail; p != null && p != head; p = p.prev) {
+ Thread t = p.thread;
+ if (t != null)
+ firstThread = t;
}
return firstThread;
}
@@ -1031,8 +1029,8 @@
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
- * getFirstQueuedThread() != Thread.currentThread() &&
- * hasQueuedThreads()}</pre>
+ * getFirstQueuedThread() != Thread.currentThread()
+ * && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@@ -1635,7 +1633,7 @@
transferAfterCancelledWait(node);
break;
}
- if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
+ if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@@ -1723,7 +1721,7 @@
timedout = transferAfterCancelledWait(node);
break;
}
- if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
+ if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@@ -1847,8 +1845,9 @@
* Initializes head and tail fields on first contention.
*/
private final void initializeSyncQueue() {
- if (U.compareAndSwapObject(this, HEAD, null, new Node()))
- tail = head;
+ Node h;
+ if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
+ tail = h;
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Wed Dec 02 09:34:55 2015 -0800
@@ -1388,7 +1388,7 @@
/**
* Queries whether any threads have ever contended to acquire this
- * synchronizer; that is if an acquire method has ever blocked.
+ * synchronizer; that is, if an acquire method has ever blocked.
*
* <p>In this implementation, this operation returns in
* constant time.
@@ -1443,13 +1443,11 @@
* guaranteeing termination.
*/
- Node t = tail;
Thread firstThread = null;
- while (t != null && t != head) {
- Thread tt = t.thread;
- if (tt != null)
- firstThread = tt;
- t = t.prev;
+ for (Node p = tail; p != null && p != head; p = p.prev) {
+ Thread t = p.thread;
+ if (t != null)
+ firstThread = t;
}
return firstThread;
}
@@ -1497,8 +1495,8 @@
* <p>An invocation of this method is equivalent to (but may be
* more efficient than):
* <pre> {@code
- * getFirstQueuedThread() != Thread.currentThread() &&
- * hasQueuedThreads()}</pre>
+ * getFirstQueuedThread() != Thread.currentThread()
+ * && hasQueuedThreads()}</pre>
*
* <p>Note that because cancellations due to interrupts and
* timeouts may occur at any time, a {@code true} return does not
@@ -2099,7 +2097,7 @@
transferAfterCancelledWait(node);
break;
}
- if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
+ if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@@ -2187,7 +2185,7 @@
timedout = transferAfterCancelledWait(node);
break;
}
- if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
+ if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
@@ -2311,8 +2309,9 @@
* Initializes head and tail fields on first contention.
*/
private final void initializeSyncQueue() {
- if (U.compareAndSwapObject(this, HEAD, null, new Node()))
- tail = head;
+ Node h;
+ if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
+ tail = h;
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Wed Dec 02 09:34:55 2015 -0800
@@ -81,12 +81,17 @@
* method is designed for use only in constructions of the form:
*
* <pre> {@code
- * while (!canProceed()) { ... LockSupport.park(this); }}</pre>
+ * while (!canProceed()) {
+ * // ensure request to unpark is visible to other threads
+ * ...
+ * LockSupport.park(this);
+ * }}</pre>
*
- * where neither {@code canProceed} nor any other actions prior to the
- * call to {@code park} entail locking or blocking. Because only one
- * permit is associated with each thread, any intermediary uses of
- * {@code park} could interfere with its intended effects.
+ * where no actions by the thread publishing a request to unpark,
+ * prior to the call to {@code park}, entail locking or blocking.
+ * Because only one permit is associated with each thread, any
+ * intermediary uses of {@code park}, including implicitly via class
+ * loading, could lead to an unresponsive thread (a "lost unpark").
*
* <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
* non-reentrant lock class:
@@ -98,26 +103,33 @@
*
* public void lock() {
* boolean wasInterrupted = false;
- * Thread current = Thread.currentThread();
- * waiters.add(current);
+ * // publish current thread for unparkers
+ * waiters.add(Thread.currentThread());
*
* // Block while not first in queue or cannot acquire lock
- * while (waiters.peek() != current ||
+ * while (waiters.peek() != Thread.currentThread() ||
* !locked.compareAndSet(false, true)) {
* LockSupport.park(this);
- * if (Thread.interrupted()) // ignore interrupts while waiting
+ * // ignore interrupts while waiting
+ * if (Thread.interrupted())
* wasInterrupted = true;
* }
*
* waiters.remove();
- * if (wasInterrupted) // reassert interrupt status on exit
- * current.interrupt();
+ * // ensure correct interrupt status on return
+ * if (wasInterrupted)
+ * Thread.currentThread().interrupt();
* }
*
* public void unlock() {
* locked.set(false);
* LockSupport.unpark(waiters.peek());
* }
+ *
+ * static {
+ * // Reduce the risk of "lost unpark" due to classloading
+ * Class<?> ensureLoaded = LockSupport.class;
+ * }
* }}</pre>
*/
public class LockSupport {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Wed Dec 02 09:34:55 2015 -0800
@@ -188,9 +188,9 @@
* try { return m.get(key); }
* finally { r.unlock(); }
* }
- * public String[] allKeys() {
+ * public List<String> allKeys() {
* r.lock();
- * try { return m.keySet().toArray(); }
+ * try { return new ArrayList<>(m.keySet()); }
* finally { r.unlock(); }
* }
* public Data put(String key, Data value) {
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java Wed Dec 02 09:34:55 2015 -0800
@@ -1253,4 +1253,55 @@
}
}
+ /**
+ * Returns the most recent application protocol value negotiated for this
+ * connection.
+ * <p>
+ * If supported by the underlying SSL/TLS/DTLS implementation,
+ * application name negotiation mechanisms such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application-Layer Protocol Negotiation (ALPN), can negotiate
+ * application-level values between peers.
+ * <p>
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this connection, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 9
+ */
+ public String getApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the application protocol value negotiated on a SSL/TLS
+ * handshake currently in progress.
+ * <p>
+ * Like {@link #getHandshakeSession()},
+ * a connection may be in the middle of a handshake. The
+ * application protocol may or may not yet be available.
+ * <p>
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this handshake, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 9
+ */
+ public String getHandshakeApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
}
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLParameters.java Wed Dec 02 09:34:55 2015 -0800
@@ -56,6 +56,17 @@
* {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and
* {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}
* and {@link SSLEngine#setSSLParameters SSLEngine.setSSLParameters()}.
+ * <p>
+ * For example:
+ *
+ * <blockquote><pre>
+ * SSLParameters p = sslSocket.getSSLParameters();
+ * p.setProtocols(new String[] { "TLSv1.2" });
+ * p.setCipherSuites(
+ * new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", ... });
+ * p.setApplicationProtocols(new String[] {"h2", "http/1.1"});
+ * sslSocket.setSSLParameters(p);
+ * </pre></blockquote>
*
* @see SSLSocket
* @see SSLEngine
@@ -76,6 +87,7 @@
private boolean preferLocalCipherSuites;
private boolean enableRetransmissions = true;
private int maximumPacketSize = 0;
+ private String[] applicationProtocols = new String[0];
/**
* Constructs SSLParameters.
@@ -480,7 +492,7 @@
*
* @see #getEnableRetransmissions()
*
- * @since 1.9
+ * @since 9
*/
public void setEnableRetransmissions(boolean enableRetransmissions) {
this.enableRetransmissions = enableRetransmissions;
@@ -495,7 +507,7 @@
*
* @see #setEnableRetransmissions(boolean)
*
- * @since 1.9
+ * @since 9
*/
public boolean getEnableRetransmissions() {
return enableRetransmissions;
@@ -523,7 +535,7 @@
*
* @see #getMaximumPacketSize()
*
- * @since 1.9
+ * @since 9
*/
public void setMaximumPacketSize(int maximumPacketSize) {
if (maximumPacketSize < 0) {
@@ -563,11 +575,80 @@
*
* @see #setMaximumPacketSize(int)
*
- * @since 1.9
+ * @since 9
*/
public int getMaximumPacketSize() {
return maximumPacketSize;
}
+ /**
+ * Returns a prioritized array of application-layer protocol names that
+ * can be negotiated over the SSL/TLS/DTLS protocols.
+ * <p>
+ * The array could be empty (zero-length), in which case protocol
+ * indications will not be used.
+ * <p>
+ * This method will return a new array each time it is invoked.
+ *
+ * @return a non-null, possibly zero-length array of application protocol
+ * {@code String}s. The array is ordered based on protocol
+ * preference, with {@code protocols[0]} being the most preferred.
+ * @see #setApplicationProtocols
+ * @since 9
+ */
+ public String[] getApplicationProtocols() {
+ return applicationProtocols.clone();
+ }
+
+ /**
+ * Sets the prioritized array of application-layer protocol names that
+ * can be negotiated over the SSL/TLS/DTLS protocols.
+ * <p>
+ * If application-layer protocols are supported by the underlying
+ * SSL/TLS implementation, this method configures which values can
+ * be negotiated by protocols such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application Layer Protocol Negotiation (ALPN).
+ * <p>
+ * If this end of the connection is expected to offer application protocol
+ * values, all protocols configured by this method will be sent to the
+ * peer.
+ * <p>
+ * If this end of the connection is expected to select the application
+ * protocol value, the {@code protocols} configured by this method are
+ * compared with those sent by the peer. The first matched value becomes
+ * the negotiated value. If none of the {@code protocols} were actually
+ * requested by the peer, the underlying protocol will determine what
+ * action to take. (For example, ALPN will send a
+ * {@code "no_application_protocol"} alert and terminate the connection.)
+ * <p>
+ * @implSpec
+ * This method will make a copy of the {@code protocols} array.
+ *
+ * @param protocols an ordered array of application protocols,
+ * with {@code protocols[0]} being the most preferred.
+ * If the array is empty (zero-length), protocol
+ * indications will not be used.
+ * @throws IllegalArgumentException if protocols is null, or if
+ * any element in a non-empty array is null or an
+ * empty (zero-length) string
+ * @see #getApplicationProtocols
+ * @since 9
+ */
+ public void setApplicationProtocols(String[] protocols) {
+ if (protocols == null) {
+ throw new IllegalArgumentException("protocols was null");
+ }
+
+ String[] tempProtocols = protocols.clone();
+
+ for (String p : tempProtocols) {
+ if (p == null || p.equals("")) {
+ throw new IllegalArgumentException(
+ "An element of protocols was null/empty");
+ }
+ }
+ applicationProtocols = tempProtocols;
+ }
}
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -662,4 +662,55 @@
}
}
+ /**
+ * Returns the most recent application protocol value negotiated for this
+ * connection.
+ * <p>
+ * If supported by the underlying SSL/TLS/DTLS implementation,
+ * application name negotiation mechanisms such as <a
+ * href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
+ * Application-Layer Protocol Negotiation (ALPN), can negotiate
+ * application-level values between peers.
+ * <p>
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this connection, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 9
+ */
+ public String getApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the application protocol value negotiated on a SSL/TLS
+ * handshake currently in progress.
+ * <p>
+ * Like {@link #getHandshakeSession()},
+ * a connection may be in the middle of a handshake. The
+ * application protocol may or may not yet be available.
+ * <p>
+ * @implSpec
+ * The implementation in this class throws
+ * {@code UnsupportedOperationException} and performs no other action.
+ *
+ * @return null if it has not yet been determined if application
+ * protocols might be used for this handshake, an empty
+ * {@code String} if application protocols values will not
+ * be used, or a non-empty application protocol {@code String}
+ * if a value was successfully negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ * @since 9
+ */
+ public String getHandshakeApplicationProtocol() {
+ throw new UnsupportedOperationException();
+ }
}
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,13 +31,12 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.ZonedDateTime;
+import java.util.Optional;
import java.util.ResourceBundle;
import java.util.function.Function;
import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
+import java.util.function.Predicate;
import java.util.function.Supplier;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
import sun.util.logging.PlatformLogger;
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
@@ -169,42 +168,55 @@
// Returns the caller's class and method's name; best effort
// if cannot infer, return the logger's name.
private String getCallerInfo() {
- String sourceClassName = null;
- String sourceMethodName = null;
+ Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
+ if (frame.isPresent()) {
+ return frame.get().getClassName() + " " + frame.get().getMethodName();
+ } else {
+ return name;
+ }
+ }
- JavaLangAccess access = SharedSecrets.getJavaLangAccess();
- Throwable throwable = new Throwable();
- int depth = access.getStackTraceDepth(throwable);
+ /*
+ * CallerFinder is a stateful predicate.
+ */
+ static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
+ static final StackWalker WALKER = StackWalker.getInstance();
- String logClassName = "sun.util.logging.PlatformLogger";
- String simpleLoggerClassName = "jdk.internal.logger.SimpleConsoleLogger";
- boolean lookingForLogger = true;
- for (int ix = 0; ix < depth; ix++) {
- // Calling getStackTraceElement directly prevents the VM
- // from paying the cost of building the entire stack frame.
- final StackTraceElement frame =
- access.getStackTraceElement(throwable, ix);
- final String cname = frame.getClassName();
+ /**
+ * Returns StackFrame of the caller's frame.
+ * @return StackFrame of the caller's frame.
+ */
+ Optional<StackWalker.StackFrame> get() {
+ return WALKER.walk((s) -> s.filter(this).findFirst());
+ }
+
+ private boolean lookingForLogger = true;
+ /**
+ * Returns true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ *
+ * @param t The frame info.
+ * @return true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ */
+ @Override
+ public boolean test(StackWalker.StackFrame t) {
+ final String cname = t.getClassName();
+ // We should skip all frames until we have found the logger,
+ // because these frames could be frames introduced by e.g. custom
+ // sub classes of Handler.
if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
- if (cname.equals(logClassName) || cname.equals(simpleLoggerClassName)) {
- lookingForLogger = false;
- }
- } else {
- if (skipLoggingFrame(cname)) continue;
- if (!cname.equals(logClassName) && !cname.equals(simpleLoggerClassName)) {
- // We've found the relevant frame.
- sourceClassName = cname;
- sourceMethodName = frame.getMethodName();
- break;
- }
+ lookingForLogger = !isLoggerImplFrame(cname);
+ return false;
}
+ // We've found the relevant frame.
+ return !skipLoggingFrame(cname) && !isLoggerImplFrame(cname);
}
- if (sourceClassName != null) {
- return sourceClassName + " " + sourceMethodName;
- } else {
- return name;
+ private boolean isLoggerImplFrame(String cname) {
+ return (cname.equals("sun.util.logging.PlatformLogger") ||
+ cname.equals("jdk.internal.logger.SimpleConsoleLogger"));
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Wed Dec 02 09:34:55 2015 -0800
@@ -103,16 +103,6 @@
void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
/**
- * Returns the number of stack frames represented by the given throwable.
- */
- int getStackTraceDepth(Throwable t);
-
- /**
- * Returns the ith StackTraceElement for the given throwable.
- */
- StackTraceElement getStackTraceElement(Throwable t, int i);
-
- /**
* Returns a new string backed by the provided character array. The
* character array is not copied and must never be modified after the
* String is created, in order to fulfill String's contract.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangInvokeAccess.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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.internal.misc;
+
+public interface JavaLangInvokeAccess {
+ /**
+ * Create a new MemberName instance
+ */
+ Object newMemberName();
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Dec 02 09:34:55 2015 -0800
@@ -45,6 +45,7 @@
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static JavaUtilJarAccess javaUtilJarAccess;
private static JavaLangAccess javaLangAccess;
+ private static JavaLangInvokeAccess javaLangInvokeAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
private static JavaNetAccess javaNetAccess;
@@ -80,6 +81,20 @@
return javaLangAccess;
}
+ public static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) {
+ javaLangInvokeAccess = jlia;
+ }
+
+ public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
+ if (javaLangInvokeAccess == null) {
+ try {
+ Class<?> c = Class.forName("java.lang.invoke.MemberName");
+ unsafe.ensureClassInitialized(c);
+ } catch (ClassNotFoundException e) {};
+ }
+ return javaLangInvokeAccess;
+ }
+
public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
javaLangRefAccess = jlra;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/vm/annotation/Contended.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.vm.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>An annotation expressing that objects and/or their fields are
+ * expected to encounter memory contention, generally in the form of
+ * "false sharing". This annotation serves as a hint that such objects
+ * and fields should reside in locations isolated from those of other
+ * objects or fields. Susceptibility to memory contention is a
+ * property of the intended usages of objects and fields, not their
+ * types or qualifiers. The effects of this annotation will nearly
+ * always add significant space overhead to objects. The use of
+ * {@code @Contended} is warranted only when the performance impact of
+ * this time/space tradeoff is intrinsically worthwhile; for example,
+ * in concurrent contexts in which each instance of the annotated
+ * class is often accessed by a different thread.
+ *
+ * <p>A {@code @Contended} field annotation may optionally include a
+ * <i>contention group</i> tag. A contention group defines a set of one
+ * or more fields that collectively must be isolated from all other
+ * contention groups. The fields in the same contention group may not be
+ * pairwise isolated. With no contention group tag (or with the default
+ * empty tag: "") each {@code @Contended} field resides in its own
+ * <i>distinct</i> and <i>anonymous</i> contention group.
+ *
+ * <p>When the annotation is used at the class level, the effect is
+ * equivalent to grouping all the declared fields not already having the
+ * {@code @Contended} annotation into the same anonymous group.
+ * With the class level annotation, implementations may choose different
+ * isolation techniques, such as isolating the entire object, rather than
+ * isolating distinct fields. A contention group tag has no meaning
+ * in a class level {@code @Contended} annotation, and is ignored.
+ *
+ * <p>The class level {@code @Contended} annotation is not inherited and has
+ * no effect on the fields declared in any sub-classes. The effects of all
+ * {@code @Contended} annotations, however, remain in force for all
+ * subclass instances, providing isolation of all the defined contention
+ * groups. Contention group tags are not inherited, and the same tag used
+ * in a superclass and subclass, represent distinct contention groups.
+ *
+ * @since 1.8
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.TYPE})
+public @interface Contended {
+
+ /**
+ * The (optional) contention group tag.
+ * This tag is only meaningful for field level annotations.
+ *
+ * @return contention group tag.
+ */
+ String value() default "";
+}
--- a/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java Wed Dec 02 09:34:55 2015 -0800
@@ -113,7 +113,7 @@
}
public static String unparse(MethodType type) {
- return unparseMethod(type.returnType(), type.parameterList());
+ return unparseMethod(type.returnType(), type.parameterArray());
}
public static String unparse(Object type) {
@@ -134,6 +134,16 @@
return sb.toString();
}
+ public static String unparseMethod(Class<?> rtype, Class<?>[] ptypes) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('(');
+ for (Class<?> pt : ptypes)
+ unparseSig(pt, sb);
+ sb.append(')');
+ unparseSig(rtype, sb);
+ return sb.toString();
+ }
+
private static void unparseSig(Class<?> t, StringBuilder sb) {
char c = Wrapper.forBasicType(t).basicTypeChar();
if (c != 'L') {
--- a/jdk/src/java.base/share/classes/sun/misc/Contended.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * <p>An annotation expressing that objects and/or their fields are
- * expected to encounter memory contention, generally in the form of
- * "false sharing". This annotation serves as a hint that such objects
- * and fields should reside in locations isolated from those of other
- * objects or fields. Susceptibility to memory contention is a
- * property of the intended usages of objects and fields, not their
- * types or qualifiers. The effects of this annotation will nearly
- * always add significant space overhead to objects. The use of
- * {@code @Contended} is warranted only when the performance impact of
- * this time/space tradeoff is intrinsically worthwhile; for example,
- * in concurrent contexts in which each instance of the annotated
- * class is often accessed by a different thread.
- *
- * <p>A {@code @Contended} field annotation may optionally include a
- * <i>contention group</i> tag. A contention group defines a set of one
- * or more fields that collectively must be isolated from all other
- * contention groups. The fields in the same contention group may not be
- * pairwise isolated. With no contention group tag (or with the default
- * empty tag: "") each {@code @Contended} field resides in its own
- * <i>distinct</i> and <i>anonymous</i> contention group.
- *
- * <p>When the annotation is used at the class level, the effect is
- * equivalent to grouping all the declared fields not already having the
- * {@code @Contended} annotation into the same anonymous group.
- * With the class level annotation, implementations may choose different
- * isolation techniques, such as isolating the entire object, rather than
- * isolating distinct fields. A contention group tag has no meaning
- * in a class level {@code @Contended} annotation, and is ignored.
- *
- * <p>The class level {@code @Contended} annotation is not inherited and has
- * no effect on the fields declared in any sub-classes. The effects of all
- * {@code @Contended} annotations, however, remain in force for all
- * subclass instances, providing isolation of all the defined contention
- * groups. Contention group tags are not inherited, and the same tag used
- * in a superclass and subclass, represent distinct contention groups.
- *
- * @since 1.8
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.FIELD, ElementType.TYPE})
-public @interface Contended {
-
- /**
- * The (optional) contention group tag.
- * This tag is only meaningful for field level annotations.
- *
- * @return contention group tag.
- */
- String value() default "";
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ALPNExtension.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,168 @@
+/*
+ * 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 sun.security.ssl;
+
+import java.io.IOException;
+import java.nio.charset.*;
+import java.util.*;
+
+import javax.net.ssl.*;
+
+/*
+ * [RFC 7301]
+ * This TLS extension facilitates the negotiation of application-layer protocols
+ * within the TLS handshake. Clients MAY include an extension of type
+ * "application_layer_protocol_negotiation" in the (extended) ClientHello
+ * message. The "extension_data" field of this extension SHALL contain a
+ * "ProtocolNameList" value:
+ *
+ * enum {
+ * application_layer_protocol_negotiation(16), (65535)
+ * } ExtensionType;
+ *
+ * opaque ProtocolName<1..2^8-1>;
+ *
+ * struct {
+ * ProtocolName protocol_name_list<2..2^16-1>
+ * } ProtocolNameList;
+ */
+final class ALPNExtension extends HelloExtension {
+
+ final static int ALPN_HEADER_LENGTH = 1;
+ final static int MAX_APPLICATION_PROTOCOL_LENGTH = 255;
+ final static int MAX_APPLICATION_PROTOCOL_LIST_LENGTH = 65535;
+ private int listLength = 0; // ProtocolNameList length
+ private List<String> protocolNames = null;
+
+ // constructor for ServerHello
+ ALPNExtension(String protocolName) throws SSLException {
+ this(new String[]{ protocolName });
+ }
+
+ // constructor for ClientHello
+ ALPNExtension(String[] protocolNames) throws SSLException {
+ super(ExtensionType.EXT_ALPN);
+ if (protocolNames.length == 0) { // never null, never empty
+ throw new IllegalArgumentException(
+ "The list of application protocols cannot be empty");
+ }
+ this.protocolNames = Arrays.asList(protocolNames);
+ for (String p : protocolNames) {
+ int length = p.getBytes(StandardCharsets.UTF_8).length;
+ if (length == 0) {
+ throw new SSLProtocolException(
+ "Application protocol name is empty");
+ }
+ if (length <= MAX_APPLICATION_PROTOCOL_LENGTH) {
+ listLength += length + ALPN_HEADER_LENGTH;
+ } else {
+ throw new SSLProtocolException(
+ "Application protocol name is too long: " + p);
+ }
+ if (listLength > MAX_APPLICATION_PROTOCOL_LIST_LENGTH) {
+ throw new SSLProtocolException(
+ "Application protocol name list is too long");
+ }
+ }
+ }
+
+ // constructor for ServerHello for parsing ALPN extension
+ ALPNExtension(HandshakeInStream s, int len) throws IOException {
+ super(ExtensionType.EXT_ALPN);
+
+ if (len >= 2) {
+ listLength = s.getInt16(); // list length
+ if (listLength < 2 || listLength + 2 != len) {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: incorrect list length " +
+ "(length=" + listLength + ")");
+ }
+ } else {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: insufficient data " +
+ "(length=" + len + ")");
+ }
+
+ int remaining = listLength;
+ this.protocolNames = new ArrayList<>();
+ while (remaining > 0) {
+ // opaque ProtocolName<1..2^8-1>; // RFC 7301
+ byte[] bytes = s.getBytes8();
+ if (bytes.length == 0) {
+ throw new SSLProtocolException("Invalid " + type +
+ " extension: empty application protocol name");
+ }
+ String p =
+ new String(bytes, StandardCharsets.UTF_8); // app protocol
+ protocolNames.add(p);
+ remaining -= bytes.length + ALPN_HEADER_LENGTH;
+ }
+
+ if (remaining != 0) {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension: extra data " +
+ "(length=" + remaining + ")");
+ }
+ }
+
+ List<String> getPeerAPs() {
+ return protocolNames;
+ }
+
+ /*
+ * Return the length in bytes, including extension type and length fields.
+ */
+ @Override
+ int length() {
+ return 6 + listLength;
+ }
+
+ @Override
+ void send(HandshakeOutStream s) throws IOException {
+ s.putInt16(type.id);
+ s.putInt16(listLength + 2); // length of extension_data
+ s.putInt16(listLength); // length of ProtocolNameList
+
+ for (String p : protocolNames) {
+ s.putBytes8(p.getBytes(StandardCharsets.UTF_8));
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (protocolNames == null || protocolNames.isEmpty()) {
+ sb.append("<empty>");
+ } else {
+ for (String protocolName : protocolNames) {
+ sb.append("[" + protocolName + "]");
+ }
+ }
+
+ return "Extension " + type +
+ ", protocol names: " + sb;
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Alerts.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Alerts.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -83,6 +83,9 @@
static final byte alert_bad_certificate_status_response = 113;
static final byte alert_bad_certificate_hash_value = 114;
+ // from RFC 7301 (TLS ALPN Extension)
+ static final byte alert_no_application_protocol = 120;
+
static String alertDescription(byte code) {
switch (code) {
@@ -144,6 +147,8 @@
return "bad_certificate_status_response";
case alert_bad_certificate_hash_value:
return "bad_certificate_hash_value";
+ case alert_no_application_protocol:
+ return "no_application_protocol";
default:
return "<UNKNOWN ALERT: " + (code & 0x0ff) + ">";
@@ -189,6 +194,7 @@
case alert_unrecognized_name:
case alert_bad_certificate_status_response:
case alert_bad_certificate_hash_value:
+ case alert_no_application_protocol:
e = new SSLHandshakeException(reason);
break;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java Wed Dec 02 09:34:55 2015 -0800
@@ -764,7 +764,7 @@
final boolean N = (SunJSSE.isFIPS() == false);
/*
- * TLS Cipher Suite Registry, as of August 2010.
+ * TLS Cipher Suite Registry, as of November 2015.
*
* http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
*
@@ -773,77 +773,77 @@
* 192-254 Specification Required Refers to value of first byte
* 255 Reserved for Private Use Refers to value of first byte
*
- * Value Description Reference
- * 0x00,0x00 TLS_NULL_WITH_NULL_NULL [RFC5246]
- * 0x00,0x01 TLS_RSA_WITH_NULL_MD5 [RFC5246]
- * 0x00,0x02 TLS_RSA_WITH_NULL_SHA [RFC5246]
- * 0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 [RFC4346]
- * 0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 [RFC5246]
- * 0x00,0x05 TLS_RSA_WITH_RC4_128_SHA [RFC5246]
- * 0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 [RFC4346]
- * 0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA [RFC5469]
- * 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 [RFC4346]
- * 0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 [RFC5246]
- * 0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
- * 0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA [RFC5469]
- * 0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA [RFC5246]
- * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]
- * 0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA [RFC2712]
- * 0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA [RFC2712]
- * 0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA [RFC2712]
- * 0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA [RFC2712]
- * 0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 [RFC2712]
- * 0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 [RFC2712]
- * 0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 [RFC2712]
- * 0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 [RFC2712]
- * 0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA [RFC2712]
- * 0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA [RFC2712]
- * 0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA [RFC2712]
- * 0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [RFC2712]
- * 0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 [RFC2712]
- * 0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 [RFC2712]
- * 0x00,0x2C TLS_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA [RFC4785]
- * 0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA [RFC5246]
- * 0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA [RFC5246]
- * 0x00,0x3B TLS_RSA_WITH_NULL_SHA256 [RFC5246]
- * 0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
- * 0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * Value Description Reference
+ * 0x00,0x00 TLS_NULL_WITH_NULL_NULL [RFC5246]
+ * 0x00,0x01 TLS_RSA_WITH_NULL_MD5 [RFC5246]
+ * 0x00,0x02 TLS_RSA_WITH_NULL_SHA [RFC5246]
+ * 0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x05 TLS_RSA_WITH_RC4_128_SHA [RFC5246]
+ * 0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 [RFC4346]
+ * 0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA [RFC5469]
+ * 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]
+ * 0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA [RFC2712]
+ * 0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA [RFC2712]
+ * 0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA [RFC2712]
+ * 0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA [RFC2712]
+ * 0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 [RFC2712]
+ * 0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 [RFC2712]
+ * 0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 [RFC2712]
+ * 0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 [RFC2712]
+ * 0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA [RFC2712]
+ * 0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA [RFC2712]
+ * 0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA [RFC2712]
+ * 0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 [RFC2712]
+ * 0x00,0x2C TLS_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3B TLS_RSA_WITH_NULL_SHA256 [RFC5246]
+ * 0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
* 0x00,0x47-4F Reserved to avoid conflicts with
* deployed implementations [Pasi_Eronen]
* 0x00,0x50-58 Reserved to avoid conflicts [Pasi Eronen]
@@ -852,143 +852,261 @@
* 0x00,0x5D-5F Unassigned
* 0x00,0x60-66 Reserved to avoid conflicts with widely
* deployed implementations [Pasi_Eronen]
- * 0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
- * 0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 [RFC5246]
- * 0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 [RFC5246]
* 0x00,0x6E-83 Unassigned
- * 0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
- * 0x00,0x8A TLS_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA [RFC4279]
- * 0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
- * 0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA [RFC4279]
- * 0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA [RFC4279]
- * 0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA [RFC4162]
- * 0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 [RFC5288]
- * 0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 [RFC5288]
- * 0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
- * 0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
- * 0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
- * 0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
- * 0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 [RFC5487]
- * 0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [RFC5487]
- * 0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
- * 0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
- * 0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x8A TLS_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
* 0x00,0xC6-FE Unassigned
- * 0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV [RFC5746]
- * 0x01-BF,* Unassigned
- * 0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA [RFC4492]
- * 0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA [RFC4492]
- * 0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA [RFC4492]
- * 0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA [RFC4492]
- * 0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA [RFC4492]
- * 0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA [RFC5054]
- * 0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA [RFC5054]
- * 0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA [RFC5054]
- * 0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
- * 0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
- * 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
- * 0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
- * 0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA [RFC5489]
- * 0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC5489]
- * 0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA [RFC5489]
- * 0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA [RFC5489]
- * 0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5489]
- * 0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5489]
- * 0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA [RFC5489]
- * 0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 [RFC5489]
- * 0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 [RFC5489]
- * 0xC0,0x3C-FF Unassigned
+ * 0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV [RFC5746]
+ * 0x01-55,* Unassigned
+ * 0x56,0x00 TLS_FALLBACK_SCSV [RFC7507]
+ * 0x56,0x01-0xC0,0x00 Unassigned
+ * 0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA [RFC5489]
+ * 0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC5489]
+ * 0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA [RFC5489]
+ * 0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA [RFC5489]
+ * 0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5489]
+ * 0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5489]
+ * 0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA [RFC5489]
+ * 0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 [RFC5489]
+ * 0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 [RFC5489]
+ * 0xC0,0x3C TLS_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x3D TLS_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x3E TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x3F TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x40 TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x41 TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x42 TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x43 TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x44 TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x45 TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x46 TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x47 TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x48 TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x49 TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4A TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4B TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4C TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4D TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x4E TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x4F TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x50 TLS_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x51 TLS_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x52 TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x53 TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x54 TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x55 TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x56 TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x57 TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x58 TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x59 TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5A TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5B TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5C TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5D TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x5E TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x5F TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x60 TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x61 TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x62 TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x63 TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x64 TLS_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x65 TLS_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x66 TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x67 TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x68 TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x69 TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x6A TLS_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6B TLS_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x6C TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6D TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x6E TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 [RFC6209]
+ * 0xC0,0x6F TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 [RFC6209]
+ * 0xC0,0x70 TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 [RFC6209]
+ * 0xC0,0x71 TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 [RFC6209]
+ * 0xC0,0x72 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x73 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x74 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x75 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x76 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x77 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x78 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x79 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x7A TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7B TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x7C TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7D TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x7E TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x7F TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x80 TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x81 TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x82 TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x83 TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x84 TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x85 TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x86 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x87 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x88 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x89 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8A TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8B TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8C TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8D TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x8E TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x8F TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x90 TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x91 TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x92 TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 [RFC6367]
+ * 0xC0,0x93 TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 [RFC6367]
+ * 0xC0,0x94 TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x95 TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x96 TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x97 TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x98 TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x99 TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x9A TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 [RFC6367]
+ * 0xC0,0x9B TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 [RFC6367]
+ * 0xC0,0x9C TLS_RSA_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0x9D TLS_RSA_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0x9E TLS_DHE_RSA_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0x9F TLS_DHE_RSA_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA0 TLS_RSA_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA1 TLS_RSA_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xA2 TLS_DHE_RSA_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA3 TLS_DHE_RSA_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xA4 TLS_PSK_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0xA5 TLS_PSK_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA6 TLS_DHE_PSK_WITH_AES_128_CCM [RFC6655]
+ * 0xC0,0xA7 TLS_DHE_PSK_WITH_AES_256_CCM [RFC6655]
+ * 0xC0,0xA8 TLS_PSK_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xA9 TLS_PSK_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xAA TLS_PSK_DHE_WITH_AES_128_CCM_8 [RFC6655]
+ * 0xC0,0xAB TLS_PSK_DHE_WITH_AES_256_CCM_8 [RFC6655]
+ * 0xC0,0xAC TLS_ECDHE_ECDSA_WITH_AES_128_CCM [RFC7251]
+ * 0xC0,0xAD TLS_ECDHE_ECDSA_WITH_AES_256_CCM [RFC7251]
+ * 0xC0,0xAE TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 [RFC7251]
+ * 0xC0,0xAF TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 [RFC7251]
+ * 0xC0,0xB0-FF Unassigned
* 0xC1-FD,* Unassigned
* 0xFE,0x00-FD Unassigned
* 0xFE,0xFE-FF Reserved to avoid conflicts with widely
@@ -1289,149 +1407,276 @@
// the debug output.
// remaining unsupported ciphersuites defined in RFC2246.
- add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
- add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
- add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
- add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
- add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
- add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
- add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
- add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
+ add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
+ add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
+ add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
+ add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
+ add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
+ add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
+ add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
+ add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
// SSL 3.0 Fortezza ciphersuites
- add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
- add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
+ add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
+ add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
// 1024/56 bit exportable ciphersuites from expired internet draft
- add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
- add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
- add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
- add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
- add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
+ add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
+ add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
+ add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
// Netscape old and new SSL 3.0 FIPS ciphersuites
// see http://www.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html
- add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
- add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
- add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
- add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
+ add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
+ add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
+ add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
+ add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
// Unsupported Kerberos cipher suites from RFC 2712
- add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
- add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
+ add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
+ add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
// Unsupported cipher suites from RFC 4162
- add("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096);
- add("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097);
- add("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098);
- add("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099);
- add("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a);
- add("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b);
+ add("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096);
+ add("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097);
+ add("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098);
+ add("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099);
+ add("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a);
+ add("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b);
// Unsupported cipher suites from RFC 4279
- add("TLS_PSK_WITH_RC4_128_SHA", 0x008a);
- add("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b);
- add("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c);
- add("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d);
- add("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e);
- add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f);
- add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090);
- add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091);
- add("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092);
- add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093);
- add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094);
- add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095);
+ add("TLS_PSK_WITH_RC4_128_SHA", 0x008a);
+ add("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d);
+ add("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e);
+ add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091);
+ add("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092);
+ add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095);
// Unsupported cipher suites from RFC 4785
- add("TLS_PSK_WITH_NULL_SHA", 0x002c);
- add("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d);
- add("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e);
+ add("TLS_PSK_WITH_NULL_SHA", 0x002c);
+ add("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d);
+ add("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e);
// Unsupported cipher suites from RFC 5246
- add("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030);
- add("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031);
- add("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036);
- add("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037);
- add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e);
- add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f);
- add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068);
- add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069);
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037);
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069);
// Unsupported cipher suites from RFC 5288
- add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0);
- add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1);
- add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4);
- add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5);
+ add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0);
+ add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1);
+ add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4);
+ add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5);
// Unsupported cipher suites from RFC 5487
- add("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8);
- add("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9);
- add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa);
- add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab);
- add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac);
- add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad);
- add("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae);
- add("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af);
- add("TLS_PSK_WITH_NULL_SHA256", 0x00b0);
- add("TLS_PSK_WITH_NULL_SHA384", 0x00b1);
- add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2);
- add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3);
- add("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4);
- add("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5);
- add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6);
- add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7);
- add("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8);
- add("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9);
+ add("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8);
+ add("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9);
+ add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa);
+ add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab);
+ add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac);
+ add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af);
+ add("TLS_PSK_WITH_NULL_SHA256", 0x00b0);
+ add("TLS_PSK_WITH_NULL_SHA384", 0x00b1);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3);
+ add("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4);
+ add("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7);
+ add("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8);
+ add("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9);
// Unsupported cipher suites from RFC 5932
- add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041);
- add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042);
- add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043);
- add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044);
- add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045);
- add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046);
- add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084);
- add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085);
- add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086);
- add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087);
- add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088);
- add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089);
- add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba);
- add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb);
- add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc);
- add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd);
- add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be);
- add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf);
- add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0);
- add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1);
- add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2);
- add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3);
- add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4);
- add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5);
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089);
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5);
+
+ // TLS Fallback Signaling Cipher Suite Value (SCSV) RFC 7507
+ add("TLS_FALLBACK_SCSV", 0x5600);
// Unsupported cipher suites from RFC 5054
- add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a);
- add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b);
- add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c);
- add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d);
- add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e);
- add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f);
- add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020);
- add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021);
- add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022);
+ add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a);
+ add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b);
+ add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c);
+ add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d);
+ add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e);
+ add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f);
+ add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020);
+ add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021);
+ add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022);
// Unsupported cipher suites from RFC 5489
- add("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033);
- add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034);
- add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035);
- add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036);
- add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037);
- add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a);
- add("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b);
+ add("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033);
+ add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b);
+
+ // Unsupported cipher suites from RFC 6209
+ add("TLS_RSA_WITH_ARIA_128_CBC_SHA256", 0xc03c);
+ add("TLS_RSA_WITH_ARIA_256_CBC_SHA384", 0xc03d);
+ add("TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", 0xc03e);
+ add("TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", 0xc03f);
+ add("TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc040);
+ add("TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc041);
+ add("TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", 0xc042);
+ add("TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", 0xc043);
+ add("TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc044);
+ add("TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc045);
+ add("TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", 0xc046);
+ add("TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", 0xc047);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc048);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc049);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc04a);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc04b);
+ add("TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04c);
+ add("TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04d);
+ add("TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04e);
+ add("TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04f);
+ add("TLS_RSA_WITH_ARIA_128_GCM_SHA256", 0xc050);
+ add("TLS_RSA_WITH_ARIA_256_GCM_SHA384", 0xc051);
+ add("TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc052);
+ add("TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc053);
+ add("TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc054);
+ add("TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc055);
+ add("TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", 0xc056);
+ add("TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", 0xc057);
+ add("TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", 0xc058);
+ add("TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", 0xc059);
+ add("TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", 0xc05a);
+ add("TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", 0xc05b);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05c);
+ add("TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05d);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05e);
+ add("TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05f);
+ add("TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc060);
+ add("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc061);
+ add("TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc062);
+ add("TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc063);
+ add("TLS_PSK_WITH_ARIA_128_CBC_SHA256", 0xc064);
+ add("TLS_PSK_WITH_ARIA_256_CBC_SHA384", 0xc065);
+ add("TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc066);
+ add("TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc067);
+ add("TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", 0xc068);
+ add("TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", 0xc069);
+ add("TLS_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06a);
+ add("TLS_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06b);
+ add("TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06c);
+ add("TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06d);
+ add("TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06e);
+ add("TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06f);
+ add("TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc070);
+ add("TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc071);
+
+ // Unsupported cipher suites from RFC 6367
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc072);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc073);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc074);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc075);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc076);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc077);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc078);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc079);
+ add("TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07a);
+ add("TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07b);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07c);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07d);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07e);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07f);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc080);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc081);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc082);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc083);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", 0xc084);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", 0xc085);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc086);
+ add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc087);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc088);
+ add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc089);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08a);
+ add("TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08b);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08c);
+ add("TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08d);
+ add("TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc08e);
+ add("TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc08f);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc090);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc091);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc092);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc093);
+ add("TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc094);
+ add("TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc095);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc096);
+ add("TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc097);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc098);
+ add("TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc099);
+ add("TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc09a);
+ add("TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc09b);
+
+ // Unsupported cipher suites from RFC 6655
+ add("TLS_RSA_WITH_AES_128_CCM", 0xc09c);
+ add("TLS_RSA_WITH_AES_256_CCM", 0xc09d);
+ add("TLS_DHE_RSA_WITH_AES_128_CCM", 0xc09e);
+ add("TLS_DHE_RSA_WITH_AES_256_CCM", 0xc09f);
+ add("TLS_RSA_WITH_AES_128_CCM_8", 0xc0A0);
+ add("TLS_RSA_WITH_AES_256_CCM_8", 0xc0A1);
+ add("TLS_DHE_RSA_WITH_AES_128_CCM_8", 0xc0A2);
+ add("TLS_DHE_RSA_WITH_AES_256_CCM_8", 0xc0A3);
+ add("TLS_PSK_WITH_AES_128_CCM", 0xc0A4);
+ add("TLS_PSK_WITH_AES_256_CCM", 0xc0A5);
+ add("TLS_DHE_PSK_WITH_AES_128_CCM", 0xc0A6);
+ add("TLS_DHE_PSK_WITH_AES_256_CCM", 0xc0A7);
+ add("TLS_PSK_WITH_AES_128_CCM_8", 0xc0A8);
+ add("TLS_PSK_WITH_AES_256_CCM_8", 0xc0A9);
+ add("TLS_PSK_DHE_WITH_AES_128_CCM_8", 0xc0Aa);
+ add("TLS_PSK_DHE_WITH_AES_256_CCM_8", 0xc0Ab);
+
+ // Unsupported cipher suites from RFC 7251
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 0xc0Ac);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 0xc0Ad);
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 0xc0Ae);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 0xc0Af);
}
// ciphersuite SSL_NULL_WITH_NULL_NULL
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Wed Dec 02 09:34:55 2015 -0800
@@ -151,6 +151,9 @@
private static final boolean enableMFLExtension =
Debug.getBooleanProperty("jsse.enableMFLExtension", false);
+ // Whether an ALPN extension was sent in the ClientHello
+ private boolean alpnActive = false;
+
private List<SNIServerName> requestedServerNames =
Collections.<SNIServerName>emptyList();
@@ -700,6 +703,44 @@
} // Otherwise, using the value negotiated during the original
// session initiation
+ // check the ALPN extension
+ ALPNExtension serverHelloALPN =
+ (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
+
+ if (serverHelloALPN != null) {
+ // Check whether an ALPN extension was sent in ClientHello message
+ if (!alpnActive) {
+ fatalSE(Alerts.alert_unsupported_extension,
+ "Server sent " + ExtensionType.EXT_ALPN +
+ " extension when not requested by client");
+ }
+
+ List<String> protocols = serverHelloALPN.getPeerAPs();
+ // Only one application protocol name should be present
+ String p;
+ if ((protocols.size() == 1) &&
+ !((p = protocols.get(0)).isEmpty())) {
+ int i;
+ for (i = 0; i < localApl.length; i++) {
+ if (localApl[i].equals(p)) {
+ break;
+ }
+ }
+ if (i == localApl.length) {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Server has selected an application protocol name " +
+ "which was not offered by the client: " + p);
+ }
+ applicationProtocol = p;
+ } else {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Incorrect data in ServerHello " + ExtensionType.EXT_ALPN +
+ " message");
+ }
+ } else {
+ applicationProtocol = "";
+ }
+
if (resumingSession && session != null) {
setHandshakeSessionSE(session);
// Reserve the handshake state if this is a session-resumption
@@ -729,6 +770,7 @@
} else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
&& (type != ExtensionType.EXT_EC_POINT_FORMATS)
&& (type != ExtensionType.EXT_SERVER_NAME)
+ && (type != ExtensionType.EXT_ALPN)
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)
&& (type != ExtensionType.EXT_STATUS_REQUEST)
&& (type != ExtensionType.EXT_STATUS_REQUEST_V2)) {
@@ -1525,6 +1567,12 @@
clientHelloMessage.addCertStatusRequestExtension();
}
+ // Add ALPN extension
+ if (localApl != null && localApl.length > 0) {
+ clientHelloMessage.addALPNExtension(localApl);
+ alpnActive = true;
+ }
+
// reset the client random cookie
clnt_random = clientHelloMessage.clnt_random;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ExtensionType.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ExtensionType.java Wed Dec 02 09:34:55 2015 -0800
@@ -43,8 +43,7 @@
return name;
}
- static List<ExtensionType> knownExtensions =
- new ArrayList<ExtensionType>(14);
+ static List<ExtensionType> knownExtensions = new ArrayList<>(15);
static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
@@ -97,6 +96,11 @@
static final ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13
+ // extension defined in RFC 7301 (ALPN)
+ static final ExtensionType EXT_ALPN =
+ e(0x0010, "application_layer_protocol_negotiation");
+ // IANA registry value: 16
+
// extensions defined in RFC 6961
static final ExtensionType EXT_STATUS_REQUEST_V2 =
e(0x0011, "status_request_v2"); // IANA registry value: 17
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Wed Dec 02 09:34:55 2015 -0800
@@ -412,6 +412,11 @@
extensions.add(new CertStatusReqListV2Extension(itemList));
}
+ // add application_layer_protocol_negotiation extension
+ void addALPNExtension(String[] applicationProtocols) throws SSLException {
+ extensions.add(new ALPNExtension(applicationProtocols));
+ }
+
@Override
int messageType() { return ht_client_hello; }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Wed Dec 02 09:34:55 2015 -0800
@@ -116,6 +116,12 @@
List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
+ // List of local ApplicationProtocols
+ String[] localApl = null;
+
+ // Negotiated ALPN value
+ String applicationProtocol = null;
+
// The maximum expected network packet size for SSL/TLS/DTLS records.
int maximumPacketSize = 0;
@@ -481,6 +487,20 @@
}
/**
+ * Sets the Application Protocol list.
+ */
+ void setApplicationProtocols(String[] apl) {
+ this.localApl = apl;
+ }
+
+ /**
+ * Gets the "negotiated" ALPN value.
+ */
+ String getHandshakeApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ /**
* Sets the cipher suites preference.
*/
void setUseCipherSuitesOrder(boolean on) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HelloExtensions.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HelloExtensions.java Wed Dec 02 09:34:55 2015 -0800
@@ -33,8 +33,8 @@
/**
* This file contains all the classes relevant to TLS Extensions for the
* ClientHello and ServerHello messages. The extension mechanism and
- * several extensions are defined in RFC 3546. Additional extensions are
- * defined in the ECC RFC 4492.
+ * several extensions are defined in RFC 6066. Additional extensions are
+ * defined in the ECC RFC 4492 and the ALPN extension is defined in RFC 7301.
*
* Currently, only the two ECC extensions are fully supported.
*
@@ -52,6 +52,7 @@
* . SupportedEllipticCurvesExtension: the ECC supported curves extension.
* . SupportedEllipticPointFormatsExtension: the ECC supported point formats
* (compressed/uncompressed) extension.
+ * . ALPNExtension: the application_layer_protocol_negotiation extension.
*
* @since 1.6
* @author Andreas Sterbenz
@@ -85,6 +86,8 @@
new SupportedEllipticPointFormatsExtension(s, extlen);
} else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) {
extension = new RenegotiationInfoExtension(s, extlen);
+ } else if (extType == ExtensionType.EXT_ALPN) {
+ extension = new ALPNExtension(s, extlen);
} else if (extType == ExtensionType.EXT_MAX_FRAGMENT_LENGTH) {
extension = new MaxFragmentLengthExtension(s, extlen);
} else if (extType == ExtensionType.EXT_STATUS_REQUEST) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -198,6 +198,14 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
+ // Negotiated application protocol value.
+ //
+ // The value under negotiation will be obtained from handshaker.
+ String applicationProtocol = null;
+
// Have we been told whether we're client or server?
private boolean serverModeSet = false;
private boolean roleIsServer;
@@ -413,6 +421,7 @@
} else { // cs_DATA
connectionState = cs_RENEGOTIATE;
}
+
if (roleIsServer) {
handshaker = new ServerHandshaker(this, sslContext,
enabledProtocols, doClientAuth,
@@ -432,6 +441,7 @@
handshaker.setMaximumPacketSize(maximumPacketSize);
handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
+ handshaker.setApplicationProtocols(applicationProtocols);
outputRecord.initHandshaker();
}
@@ -1055,6 +1065,9 @@
handshaker.isSecureRenegotiation();
clientVerifyData = handshaker.getClientVerifyData();
serverVerifyData = handshaker.getServerVerifyData();
+ // set connection ALPN value
+ applicationProtocol =
+ handshaker.getHandshakeApplicationProtocol();
sess = handshaker.getSession();
handshakeSession = null;
@@ -2140,6 +2153,7 @@
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
params.setEnableRetransmissions(enableRetransmissions);
params.setMaximumPacketSize(maximumPacketSize);
+ params.setApplicationProtocols(applicationProtocols);
return params;
}
@@ -2174,11 +2188,13 @@
if (matchers != null) {
sniMatchers = matchers;
}
+ applicationProtocols = params.getApplicationProtocols();
if ((handshaker != null) && !handshaker.started()) {
handshaker.setIdentificationProtocol(identificationProtocol);
handshaker.setAlgorithmConstraints(algorithmConstraints);
handshaker.setMaximumPacketSize(maximumPacketSize);
+ handshaker.setApplicationProtocols(applicationProtocols);
if (roleIsServer) {
handshaker.setSNIMatchers(sniMatchers);
handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
@@ -2188,6 +2204,19 @@
}
}
+ @Override
+ public synchronized String getApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ @Override
+ public synchronized String getHandshakeApplicationProtocol() {
+ if ((handshaker != null) && !handshaker.started()) {
+ return handshaker.getHandshakeApplicationProtocol();
+ }
+ return null;
+ }
+
/**
* Returns a printable representation of this end of the connection.
*/
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -92,6 +92,9 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
/*
* Whether local cipher suites preference in server side should be
* honored during handshaking?
@@ -311,7 +314,7 @@
params.setAlgorithmConstraints(algorithmConstraints);
params.setSNIMatchers(sniMatchers);
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
-
+ params.setApplicationProtocols(applicationProtocols);
return params;
}
@@ -331,6 +334,7 @@
if (matchers != null) {
sniMatchers = params.getSNIMatchers();
}
+ applicationProtocols = params.getApplicationProtocols();
}
/**
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -210,6 +210,14 @@
Collection<SNIMatcher> sniMatchers =
Collections.<SNIMatcher>emptyList();
+ // Configured application protocol values
+ String[] applicationProtocols = new String[0];
+
+ // Negotiated application protocol value.
+ //
+ // The value under negotiation will be obtained from handshaker.
+ String applicationProtocol = null;
+
/*
* READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
* IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
@@ -1116,6 +1124,9 @@
handshaker.isSecureRenegotiation();
clientVerifyData = handshaker.getClientVerifyData();
serverVerifyData = handshaker.getServerVerifyData();
+ // set connection ALPN value
+ applicationProtocol =
+ handshaker.getHandshakeApplicationProtocol();
sess = handshaker.getSession();
handshakeSession = null;
@@ -1314,6 +1325,7 @@
} else { // cs_DATA
connectionState = cs_RENEGOTIATE;
}
+
if (roleIsServer) {
handshaker = new ServerHandshaker(this, sslContext,
enabledProtocols, doClientAuth,
@@ -1331,6 +1343,7 @@
handshaker.setMaximumPacketSize(maximumPacketSize);
handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
+ handshaker.setApplicationProtocols(applicationProtocols);
}
/**
@@ -2511,6 +2524,7 @@
params.setServerNames(serverNames);
params.setUseCipherSuitesOrder(preferLocalCipherSuites);
params.setMaximumPacketSize(maximumPacketSize);
+ params.setApplicationProtocols(applicationProtocols);
// DTLS handshake retransmissions parameter does not apply here.
@@ -2549,10 +2563,13 @@
sniMatchers = matchers;
}
+ applicationProtocols = params.getApplicationProtocols();
+
if ((handshaker != null) && !handshaker.started()) {
handshaker.setIdentificationProtocol(identificationProtocol);
handshaker.setAlgorithmConstraints(algorithmConstraints);
handshaker.setMaximumPacketSize(maximumPacketSize);
+ handshaker.setApplicationProtocols(applicationProtocols);
if (roleIsServer) {
handshaker.setSNIMatchers(sniMatchers);
handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
@@ -2562,6 +2579,19 @@
}
}
+ @Override
+ public synchronized String getApplicationProtocol() {
+ return applicationProtocol;
+ }
+
+ @Override
+ public synchronized String getHandshakeApplicationProtocol() {
+ if ((handshaker != null) && !handshaker.started()) {
+ return handshaker.getHandshakeApplicationProtocol();
+ }
+ return null;
+ }
+
//
// We allocate a separate thread to deliver handshake completion
// events. This ensures that the notifications don't block the
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Dec 02 09:34:55 2015 -0800
@@ -528,6 +528,36 @@
}
}
+ // check the ALPN extension
+ ALPNExtension clientHelloALPN = (ALPNExtension)
+ mesg.extensions.get(ExtensionType.EXT_ALPN);
+
+ if ((clientHelloALPN != null) && (localApl.length > 0)) {
+
+ // Intersect the requested and the locally supported,
+ // and save for later.
+ String negotiatedValue = null;
+ List<String> protocols = clientHelloALPN.getPeerAPs();
+
+ // Use server preference order
+ for (String ap : localApl) {
+ if (protocols.contains(ap)) {
+ negotiatedValue = ap;
+ break;
+ }
+ }
+
+ if (negotiatedValue == null) {
+ fatalSE(Alerts.alert_no_application_protocol,
+ new SSLHandshakeException(
+ "No matching ALPN values"));
+ }
+ applicationProtocol = negotiatedValue;
+
+ } else {
+ applicationProtocol = "";
+ }
+
// cookie exchange
if (isDTLS) {
HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
@@ -921,6 +951,11 @@
}
}
+ // Prepare the ALPN response
+ if (applicationProtocol != null && !applicationProtocol.isEmpty()) {
+ m1.extensions.add(new ALPNExtension(applicationProtocol));
+ }
+
if (debug != null && Debug.isOn("handshake")) {
m1.print(System.out);
System.out.println("Cipher suite: " + session.getSuite());
@@ -1415,8 +1450,8 @@
}
}
- // need EC cert signed using EC
- if (setupPrivateKeyAndChain("EC_EC") == false) {
+ // need EC cert
+ if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
if (setupEphemeralECDHKeys() == false) {
@@ -1424,15 +1459,15 @@
}
break;
case K_ECDH_RSA:
- // need EC cert signed using RSA
- if (setupPrivateKeyAndChain("EC_RSA") == false) {
+ // need EC cert
+ if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_ECDH_ECDSA:
- // need EC cert signed using EC
- if (setupPrivateKeyAndChain("EC_EC") == false) {
+ // need EC cert
+ if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
--- a/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/KeyStoreUtil.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,6 +38,7 @@
import java.security.KeyStore;
+import java.security.cert.X509Certificate;
import java.text.Collator;
import java.util.ArrayList;
@@ -68,6 +69,25 @@
};
/**
+ * Returns true if the certificate is self-signed, false otherwise.
+ */
+ public static boolean isSelfSigned(X509Certificate cert) {
+ return signedBy(cert, cert);
+ }
+
+ public static boolean signedBy(X509Certificate end, X509Certificate ca) {
+ if (!ca.getSubjectX500Principal().equals(end.getIssuerX500Principal())) {
+ return false;
+ }
+ try {
+ end.verify(ca.getPublicKey());
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
* Returns true if KeyStore has a password. This is true except for
* MSCAPI KeyStores
*/
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Wed Dec 02 09:34:55 2015 -0800
@@ -1297,7 +1297,7 @@
for (Certificate ca: keyStore.getCertificateChain(alias)) {
if (ca instanceof X509Certificate) {
X509Certificate xca = (X509Certificate)ca;
- if (!isSelfSigned(xca)) {
+ if (!KeyStoreUtil.isSelfSigned(xca)) {
dumpCert(xca, out);
}
}
@@ -1857,8 +1857,8 @@
} else {
// Print the digest of the user cert only
out.println
- (rb.getString("Certificate.fingerprint.SHA1.") +
- getCertFingerPrint("SHA1", chain[0]));
+ (rb.getString("Certificate.fingerprint.SHA.256.") +
+ getCertFingerPrint("SHA-256", chain[0]));
}
}
} else if (keyStore.entryInstanceOf(alias,
@@ -1878,8 +1878,8 @@
out.println(cert.toString());
} else {
out.println("trustedCertEntry, ");
- out.println(rb.getString("Certificate.fingerprint.SHA1.")
- + getCertFingerPrint("SHA1", cert));
+ out.println(rb.getString("Certificate.fingerprint.SHA.256.")
+ + getCertFingerPrint("SHA-256", cert));
}
} else {
out.println(rb.getString("Unknown.Entry.Type"));
@@ -2705,7 +2705,7 @@
// if certificate is self-signed, make sure it verifies
boolean selfSigned = false;
- if (isSelfSigned(cert)) {
+ if (KeyStoreUtil.isSelfSigned(cert)) {
cert.verify(cert.getPublicKey());
selfSigned = true;
}
@@ -2907,23 +2907,6 @@
private void printX509Cert(X509Certificate cert, PrintStream out)
throws Exception
{
- /*
- out.println("Owner: "
- + cert.getSubjectDN().toString()
- + "\n"
- + "Issuer: "
- + cert.getIssuerDN().toString()
- + "\n"
- + "Serial number: " + cert.getSerialNumber().toString(16)
- + "\n"
- + "Valid from: " + cert.getNotBefore().toString()
- + " until: " + cert.getNotAfter().toString()
- + "\n"
- + "Certificate fingerprints:\n"
- + "\t MD5: " + getCertFingerPrint("MD5", cert)
- + "\n"
- + "\t SHA1: " + getCertFingerPrint("SHA1", cert));
- */
MessageFormat form = new MessageFormat
(rb.getString(".PATTERN.printX509Cert"));
@@ -2933,8 +2916,7 @@
cert.getSerialNumber().toString(16),
cert.getNotBefore().toString(),
cert.getNotAfter().toString(),
- getCertFingerPrint("MD5", cert),
- getCertFingerPrint("SHA1", cert),
+ getCertFingerPrint("SHA-1", cert),
getCertFingerPrint("SHA-256", cert),
cert.getSigAlgName(),
pkey.getAlgorithm(),
@@ -2983,25 +2965,6 @@
}
/**
- * Returns true if the certificate is self-signed, false otherwise.
- */
- private boolean isSelfSigned(X509Certificate cert) {
- return signedBy(cert, cert);
- }
-
- private boolean signedBy(X509Certificate end, X509Certificate ca) {
- if (!ca.getSubjectDN().equals(end.getIssuerDN())) {
- return false;
- }
- try {
- end.verify(ca.getPublicKey());
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
* Locates a signer for a given certificate from a given keystore and
* returns the signer's certificate.
* @param cert the certificate whose signer is searched, not null
@@ -3338,7 +3301,7 @@
// find a cert in the reply who signs thisCert
int j;
for (j=i; j<replyCerts.length; j++) {
- if (signedBy(thisCert, (X509Certificate)replyCerts[j])) {
+ if (KeyStoreUtil.signedBy(thisCert, (X509Certificate)replyCerts[j])) {
tmpCert = replyCerts[i];
replyCerts[i] = replyCerts[j];
replyCerts[j] = tmpCert;
@@ -3469,7 +3432,7 @@
Vector<Certificate> chain,
Hashtable<Principal, Vector<Certificate>> certs) {
Principal issuer = certToVerify.getIssuerDN();
- if (isSelfSigned(certToVerify)) {
+ if (KeyStoreUtil.isSelfSigned(certToVerify)) {
// reached self-signed root cert;
// no verification needed because it's trusted.
chain.addElement(certToVerify);
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Resources.java Wed Dec 02 09:34:55 2015 -0800
@@ -307,7 +307,7 @@
{"Entry.type.type.", "Entry type: {0}"},
{"Certificate.chain.length.", "Certificate chain length: "},
{"Certificate.i.1.", "Certificate[{0,number,integer}]:"},
- {"Certificate.fingerprint.SHA1.", "Certificate fingerprint (SHA1): "},
+ {"Certificate.fingerprint.SHA.256.", "Certificate fingerprint (SHA-256): "},
{"Keystore.type.", "Keystore type: "},
{"Keystore.provider.", "Keystore provider: "},
{"Your.keystore.contains.keyStore.size.entry",
@@ -347,7 +347,7 @@
{".RETURN.if.same.as.for.otherAlias.",
"\t(RETURN if same as for <{0}>)"},
{".PATTERN.printX509Cert",
- "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t MD5: {5}\n\t SHA1: {6}\n\t SHA256: {7}\nSignature algorithm name: {8}\nSubject Public Key Algorithm: {9} ({10,number,#})\nVersion: {11}"},
+ "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8} ({9,number,#})\nVersion: {10}"},
{"What.is.your.first.and.last.name.",
"What is your first and last name?"},
{"What.is.the.name.of.your.organizational.unit.",
--- a/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/native/include/jvm.h Wed Dec 02 09:34:55 2015 -0800
@@ -178,6 +178,37 @@
JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index);
/*
+ * java.lang.StackWalker
+ */
+enum {
+ JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2,
+ JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
+ JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20,
+ JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100
+};
+
+JNIEXPORT jobject JNICALL
+JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
+ jint skip_frames, jint frame_count, jint start_index,
+ jobjectArray classes,
+ jobjectArray frames);
+
+JNIEXPORT jint JNICALL
+JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
+ jint frame_count, jint start_index,
+ jobjectArray classes,
+ jobjectArray frames);
+
+JNIEXPORT void JNICALL
+JVM_FillStackFrames(JNIEnv* env, jclass cls,
+ jint start_index,
+ jobjectArray stackFrames,
+ jint from_index, jint toIndex);
+
+JNIEXPORT void JNICALL
+JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+
+/*
* java.lang.Thread
*/
JNIEXPORT void JNICALL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjava/StackFrameInfo.c Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+/*
+ * Implementation of class StackFrameInfo
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_StackFrameInfo.h"
+
+
+/*
+ * Class: java_lang_StackFrameInfo
+ * Method: fillInStackFrames
+ * Signature: (I[Ljava/lang/Object;[Ljava/lang/Object;II)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_fillInStackFrames
+ (JNIEnv *env, jclass dummy, jint startIndex,
+ jobjectArray stackFrames, jint fromIndex, jint toIndex) {
+ JVM_FillStackFrames(env, dummy, startIndex,
+ stackFrames, fromIndex, toIndex);
+}
+
+/*
+ * Class: java_lang_StackFrameInfo
+ * Method: setMethodInfo
+ * Signature: (Ljava/lang/Class;)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_setMethodInfo
+ (JNIEnv *env, jobject stackframeinfo) {
+ JVM_SetMethodInfo(env, stackframeinfo);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjava/StackStreamFactory.c Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+/*
+ * Implementation of class StackStreamfactory and AbstractStackWalker
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_StackStreamFactory.h"
+#include "java_lang_StackStreamFactory_AbstractStackWalker.h"
+
+/*
+ * Class: java_lang_StackStreamFactory
+ * Method: checkStackWalkModes
+ * Signature: ()
+ */
+JNIEXPORT jboolean JNICALL Java_java_lang_StackStreamFactory_checkStackWalkModes
+ (JNIEnv *env, jclass dummy)
+{
+ return JVM_STACKWALK_FILL_CLASS_REFS_ONLY == java_lang_StackStreamFactory_FILL_CLASS_REFS_ONLY &&
+ JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE == java_lang_StackStreamFactory_FILTER_FILL_IN_STACKTRACE &&
+ JVM_STACKWALK_SHOW_HIDDEN_FRAMES == java_lang_StackStreamFactory_SHOW_HIDDEN_FRAMES &&
+ JVM_STACKWALK_FILL_LIVE_STACK_FRAMES == java_lang_StackStreamFactory_FILL_LIVE_STACK_FRAMES;
+}
+
+/*
+ * Class: java_lang_StackStreamFactory_AbstractStackWalker
+ * Method: callStackWalk
+ * Signature: (JIII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk
+ (JNIEnv *env, jobject stackstream, jlong mode, jint skipFrames, jint batchSize, jint startIndex,
+ jobjectArray classes, jobjectArray frames)
+{
+ return JVM_CallStackWalk(env, stackstream, mode, skipFrames, batchSize,
+ startIndex, classes, frames);
+}
+
+/*
+ * Class: java_lang_StackStreamFactory_AbstractStackWalker
+ * Method: fetchStackFrames
+ * Signature: (JJII[Ljava/lang/Class;[Ljava/lang/StackWalker/StackFrame;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames
+ (JNIEnv *env, jobject stackstream, jlong mode, jlong anchor,
+ jint batchSize, jint startIndex,
+ jobjectArray classes, jobjectArray frames)
+{
+ return JVM_MoreStackWalk(env, stackstream, mode, anchor, batchSize,
+ startIndex, classes, frames);
+}
--- a/jdk/src/java.base/share/native/libjimage/imageFile.cpp Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.cpp Wed Dec 02 09:34:55 2015 -0800
@@ -291,13 +291,10 @@
// Remove an image entry from the table.
void ImageFileReaderTable::remove(ImageFileReader* image) {
- s4 last = _count - 1;
- for (s4 i = 0; _count; i++) {
+ for (u4 i = 0; i < _count; i++) {
if (_table[i] == image) {
- if (i != last) {
- _table[i] = _table[last];
- _count = last;
- }
+ // Swap the last element into the found slot
+ _table[i] = _table[--_count];
break;
}
}
@@ -310,7 +307,7 @@
// Determine if image entry is in table.
bool ImageFileReaderTable::contains(ImageFileReader* image) {
- for (s4 i = 0; _count; i++) {
+ for (u4 i = 0; i < _count; i++) {
if (_table[i] == image) {
return true;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * 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 sun.nio.ch;
+
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * Creates this platform's default SelectorProvider
+ */
+
+public class DefaultSelectorProvider {
+
+ /**
+ * Prevent instantiation.
+ */
+ private DefaultSelectorProvider() { }
+
+ /**
+ * Returns the default SelectorProvider.
+ */
+ public static SelectorProvider create() {
+ return new sun.nio.ch.DevPollSelectorProvider();
+ }
+
+}
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/DefaultSelectorProvider.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.ch;
-
-import java.nio.channels.spi.SelectorProvider;
-import java.security.AccessController;
-import sun.security.action.GetPropertyAction;
-
-/**
- * Creates this platform's default SelectorProvider
- */
-
-public class DefaultSelectorProvider {
-
- /**
- * Prevent instantiation.
- */
- private DefaultSelectorProvider() { }
-
- @SuppressWarnings("unchecked")
- private static SelectorProvider createProvider(String cn) {
- Class<SelectorProvider> c;
- try {
- c = (Class<SelectorProvider>)Class.forName(cn);
- } catch (ClassNotFoundException x) {
- throw new AssertionError(x);
- }
- try {
- return c.newInstance();
- } catch (IllegalAccessException | InstantiationException x) {
- throw new AssertionError(x);
- }
-
- }
-
- /**
- * Returns the default SelectorProvider.
- */
- public static SelectorProvider create() {
- String osname = AccessController
- .doPrivileged(new GetPropertyAction("os.name"));
- if (osname.equals("SunOS"))
- return createProvider("sun.nio.ch.DevPollSelectorProvider");
- if (osname.equals("Linux"))
- return createProvider("sun.nio.ch.EPollSelectorProvider");
- return new sun.nio.ch.PollSelectorProvider();
- }
-
-}
--- a/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.base/windows/native/libjava/ProcessHandleImpl_win.c Wed Dec 02 09:34:55 2015 -0800
@@ -184,7 +184,14 @@
// Now walk the snapshot of processes, and
do {
if (wpid == pe32.th32ProcessID) {
- ppid = pe32.th32ParentProcessID;
+ // The parent PID may be stale if that process has exited
+ // and may have been reused.
+ // A valid parent's start time is the same or before the child's
+ jlong ppStartTime = Java_java_lang_ProcessHandleImpl_isAlive0(env,
+ clazz, pe32.th32ParentProcessID);
+ if (ppStartTime > 0 && ppStartTime <= startTime) {
+ ppid = pe32.th32ParentProcessID;
+ }
break;
}
} while (Process32Next(hProcessSnap, &pe32));
--- a/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.logging/share/classes/java/util/logging/LogRecord.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,9 +30,8 @@
import java.util.concurrent.atomic.AtomicLong;
import java.io.*;
import java.time.Clock;
+import java.util.function.Predicate;
-import jdk.internal.misc.JavaLangAccess;
-import jdk.internal.misc.SharedSecrets;
import static jdk.internal.logger.SimpleConsoleLogger.skipLoggingFrame;
/**
@@ -661,42 +660,58 @@
//
private void inferCaller() {
needToInferCaller = false;
- JavaLangAccess access = SharedSecrets.getJavaLangAccess();
- Throwable throwable = new Throwable();
- int depth = access.getStackTraceDepth(throwable);
+ // Skip all frames until we have found the first logger frame.
+ Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
+ frame.ifPresent(f -> {
+ setSourceClassName(f.getClassName());
+ setSourceMethodName(f.getMethodName());
+ });
- boolean lookingForLogger = true;
- for (int ix = 0; ix < depth; ix++) {
- // Calling getStackTraceElement directly prevents the VM
- // from paying the cost of building the entire stack frame.
- StackTraceElement frame =
- access.getStackTraceElement(throwable, ix);
- String cname = frame.getClassName();
- boolean isLoggerImpl = isLoggerImplFrame(cname);
- if (lookingForLogger) {
- // Skip all frames until we have found the first logger frame.
- if (isLoggerImpl) {
- lookingForLogger = false;
- }
- } else {
- if (!isLoggerImpl) {
- // skip logging/logger infrastructure and reflection calls
- if (!skipLoggingFrame(cname)) {
- // We've found the relevant frame.
- setSourceClassName(cname);
- setSourceMethodName(frame.getMethodName());
- return;
- }
- }
- }
- }
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
}
- private boolean isLoggerImplFrame(String cname) {
- // the log record could be created for a platform logger
- return (cname.equals("java.util.logging.Logger") ||
- cname.startsWith("sun.util.logging.PlatformLogger"));
+ /*
+ * CallerFinder is a stateful predicate.
+ */
+ static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
+ static final StackWalker WALKER = StackWalker.getInstance();
+
+ /**
+ * Returns StackFrame of the caller's frame.
+ * @return StackFrame of the caller's frame.
+ */
+ Optional<StackWalker.StackFrame> get() {
+ return WALKER.walk((s) -> s.filter(this).findFirst());
+ }
+
+ private boolean lookingForLogger = true;
+ /**
+ * Returns true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ *
+ * @param t The frame info.
+ * @return true if we have found the caller's frame, false if the frame
+ * must be skipped.
+ */
+ @Override
+ public boolean test(StackWalker.StackFrame t) {
+ final String cname = t.getClassName();
+ // We should skip all frames until we have found the logger,
+ // because these frames could be frames introduced by e.g. custom
+ // sub classes of Handler.
+ if (lookingForLogger) {
+ // the log record could be created for a platform logger
+ lookingForLogger = !isLoggerImplFrame(cname);
+ return false;
+ }
+ // skip logging/logger infrastructure and reflection calls
+ return !skipLoggingFrame(cname);
+ }
+
+ private boolean isLoggerImplFrame(String cname) {
+ return (cname.equals("java.util.logging.Logger") ||
+ cname.startsWith("sun.util.logging.PlatformLogger"));
+ }
}
}
--- a/jdk/src/java.sql/share/classes/java/sql/Connection.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/Connection.java Wed Dec 02 09:34:55 2015 -0800
@@ -1587,4 +1587,119 @@
default void endRequest() throws SQLException {
// Default method takes no action
}
+
+ /**
+ * Sets and validates the sharding keys for this connection.
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ *
+ * @apiNote
+ * This method validates that the sharding keys are valid for the
+ * {@code Connection}. The timeout value indicates how long the driver
+ * should wait for the {@code Connection} to verify that the sharding key
+ * is valid before {@code setShardingKeyIfValid} returns false.
+ * @param shardingKey the sharding key to be validated against this connection
+ * @param superShardingKey the super sharding key to be validated against this
+ * connection. The super sharding key may be {@code null}.
+ * @param timeout time in seconds before which the validation process is expected to
+ * be completed, otherwise the validation process is aborted. A value of 0 indicates
+ * the validation process will not time out.
+ * @return true if the connection is valid and the sharding keys are valid
+ * and set on this connection; false if the sharding keys are not valid or
+ * the timeout period expires before the operation completes.
+ * @throws SQLException if an error occurs while performing this validation;
+ * the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified
+ * without a {@code shardingKey};
+ * this method is called on a closed {@code connection}; or
+ * the {@code timeout} value is less than 0.
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default boolean setShardingKeyIfValid(ShardingKey shardingKey,
+ ShardingKey superShardingKey, int timeout)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
+ }
+
+ /**
+ * Sets and validates the sharding key for this connection.
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method validates that the sharding key is valid for the
+ * {@code Connection}. The timeout value indicates how long the driver
+ * should wait for the {@code Connection} to verify that the sharding key
+ * is valid before {@code setShardingKeyIfValid} returns false.
+ * @param shardingKey the sharding key to be validated against this connection
+ * @param timeout time in seconds before which the validation process is expected to
+ * be completed,else the validation process is aborted. A value of 0 indicates
+ * the validation process will not time out.
+ * @return true if the connection is valid and the sharding key is valid to be
+ * set on this connection; false if the sharding key is not valid or
+ * the timeout period expires before the operation completes.
+ * @throws SQLException if there is an error while performing this validation;
+ * this method is called on a closed {@code connection}; the {@code shardingkey}
+ * is {@code null}; or the {@code timeout} value is less than 0.
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
+ }
+
+ /**
+ * Specifies a shardingKey and superShardingKey to use with this Connection
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method sets the specified sharding keys but does not require a
+ * round trip to the database to validate that the sharding keys are valid
+ * for the {@code Connection}.
+ * @param shardingKey the sharding key to set on this connection.
+ * @param superShardingKey the super sharding key to set on this connection.
+ * The super sharding key may be {@code null}
+ * @throws SQLException if an error occurs setting the sharding keys;
+ * this method is called on a closed {@code connection};
+ * the {@code shardingkey} is {@code null}; or
+ * a {@code superSharedingKey} is specified without a {@code shardingKey}
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
+ }
+
+ /**
+ * Specifies a shardingKey to use with this Connection
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method sets the specified sharding key but does not require a
+ * round trip to the database to validate that the sharding key is valid
+ * for the {@code Connection}.
+ * @param shardingKey the sharding key to set on this connection.
+ * @throws SQLException if an error occurs setting the sharding key;
+ * this method is called on a closed {@code connection}; or the
+ * {@code shardkingKey} is {@code null}
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default void setShardingKey(ShardingKey shardingKey)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ConnectionBuilder.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,101 @@
+/*
+ * 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 java.sql;
+
+/**
+ * A builder created from a {@code DataSource} object,
+ * used to establish a connection to the database that the
+ * {@code data source} object represents. The connection
+ * properties that were specified for the {@code data source} are used as the
+ * default values by the {@code ConnectionBuilder}.
+ * <p>The following example illustrates the use of {@code ConnectionBuilder}
+ * to create a {@link Connection}:
+ *
+ * <pre>{@code
+ * DataSource ds = new MyDataSource();
+ * ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ * .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ * .build();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ * .build();
+ * Connection con = ds.createConnectionBuilder()
+ * .user("rafa")
+ * .password("tennis")
+ * .setShardingKey(shardingKey)
+ * .setSuperShardingKey(superShardingKey)
+ * .build();
+ * }</pre>
+ *
+ * @since 1.9
+ *
+ */
+public interface ConnectionBuilder {
+
+ /**
+ * Specifies the username to be used when creating a connection
+ *
+ * @param username the database user on whose behalf the connection is being
+ * made
+ * @return the same {@code ConnectionBuilder} instance
+ */
+ ConnectionBuilder user(String username);
+
+ /**
+ * Specifies the password to be used when creating a connection
+ *
+ * @param password the password to use for this connection. May be {@code null}
+ * @return the same {@code ConnectionBuilder} instance
+ */
+ ConnectionBuilder password(String password);
+
+ /**
+ * Specifies a {@code shardingKey} to be used when creating a connection
+ *
+ * @param shardingKey the ShardingKey. May be {@code null}
+ * @return the same {@code ConnectionBuilder} instance
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ ConnectionBuilder shardingKey(ShardingKey shardingKey);
+
+ /**
+ * Specifies a {@code superShardingKey} to be used when creating a connection
+ *
+ * @param superShardingKey the SuperShardingKey. May be {@code null}
+ * @return the same {@code ConnectionBuilder} instance
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ ConnectionBuilder superShardingKey(ShardingKey superShardingKey);
+
+ /**
+ * Returns an instance of the object defined by this builder.
+ *
+ * @return The built object
+ * @throws java.sql.SQLException If an error occurs building the object
+ */
+ Connection build() throws SQLException;
+}
--- a/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/DatabaseMetaData.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -3684,4 +3684,19 @@
return false;
}
+ // JDBC 4.3
+
+ /**
+ * Retrieves whether this database supports sharding.
+ * @implSpec
+ * The default implementation will return {@code false}
+ *
+ * @return {@code true} if this database supports sharding;
+ * {@code false} otherwise
+ * @exception SQLException if a database access error occurs
+ * @since 1.9
+ */
+ default boolean supportsSharding() throws SQLException {
+ return false;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKey.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,76 @@
+/*
+ * 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 java.sql;
+
+/**
+ * Interface used to indicate that this object represents a Sharding Key. A
+ * {@code ShardingKey} instance is only guaranteed to be compatible with the
+ * data source instance that it was derived from. A {@code ShardingKey} is
+ * created using {@link ShardingKeyBuilder}.
+ * <p>
+ * The following example illustrates the use of {@link ShardingKeyBuilder} to
+ * create a {@code ShardingKey}:
+ * <pre>
+ * {@code
+ *
+ * DataSource ds = new MyDataSource();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("abc", JDBCType.VARCHAR)
+ * .subkey(94002, JDBCType.INTEGER)
+ * .build();
+ * }
+ * </pre>
+ * <p>
+ *
+ * A {@code ShardingKey} may also be used for specifying a
+ * {@code superShardingKey}. Databases that support composite Sharding may use a
+ * {@code superShardingKey} to specify a additional level of partitioning within
+ * the Shard.
+ * <p>
+ * The following example illustrates the use of {@link ShardingKeyBuilder} to
+ * create a {@code superShardingKey} for an eastern region with a
+ * {@code ShardingKey} specified for the Pittsburgh branch office:
+ * <pre>
+ * {@code
+ *
+ * DataSource ds = new MyDataSource();
+ * ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ * .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ * .build();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ * .build();
+ * Connection con = ds.createConnectionBuilder()
+ * .superShardingKey(superShardingKey)
+ * .shardingKey(shardingKey)
+ * .build();
+ * }
+ * </pre>
+ *
+ * @since 1.9
+ */
+public interface ShardingKey {
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/java/sql/ShardingKeyBuilder.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,66 @@
+/*
+ * 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 java.sql;
+
+/**
+ * A builder created from a {@code DataSource} or {@code XADataSource} object,
+ * used to create a {@link ShardingKey} with sub-keys of supported data types.
+ * Implementations must
+ * support JDBCType.VARCHAR and may also support additional data types.
+ * <p>
+ * The following example illustrates the use of {@code ShardingKeyBuilder} to
+ * create a {@link ShardingKey}:
+ * <pre>
+ * {@code
+ *
+ * DataSource ds = new MyDataSource();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("abc", JDBCType.VARCHAR)
+ * .subkey(94002, JDBCType.INTEGER)
+ * .build();
+ * }
+ * </pre>
+ */
+public interface ShardingKeyBuilder {
+
+ /**
+ * This method will be called to add a subkey into a Sharding Key object being
+ * built. The order in which subkey method is called is important as it
+ * indicates the order of placement of the subkey within the Sharding Key.
+ *
+ * @param subkey contains the object that needs to be part of shard sub key
+ * @param subkeyType sub-key data type of type java.sql.SQLType
+ * @return this builder object
+ */
+ ShardingKeyBuilder subkey(Object subkey, SQLType subkeyType);
+
+ /**
+ * Returns an instance of the object defined by this builder.
+ *
+ * @return The built object
+ * @throws java.sql.SQLException If an error occurs building the object
+ */
+ ShardingKey build() throws SQLException;
+}
--- a/jdk/src/java.sql/share/classes/java/sql/Statement.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/java/sql/Statement.java Wed Dec 02 09:34:55 2015 -0800
@@ -1397,9 +1397,10 @@
* @param val a character string
* @return A string enclosed by single quotes with every single quote
* converted to two single quotes
- * @throws NullPointerException if val is null
+ * @throws NullPointerException if val is {@code null}
+ * @throws SQLException if a database access error occurs
*/
- default String enquoteLiteral(String val) {
+ default String enquoteLiteral(String val) throws SQLException {
return "'" + val.replace("'", "''") + "'";
}
@@ -1437,7 +1438,7 @@
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
- * <li>{@code identifier} contains a null character or double quote, and is not
+ * <li>{@code identifier} contains a {@code null} character or double quote and is not
* a simple SQL identifier.</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
@@ -1501,14 +1502,14 @@
* @throws SQLException if identifier is not a valid identifier
* @throws SQLFeatureNotSupportedException if the datasource does not support
* delimited identifiers
- * @throws NullPointerException if identifier is null
+ * @throws NullPointerException if identifier is {@code null}
*/
default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException {
int len = identifier.length();
if (len < 1 || len > 128) {
throw new SQLException("Invalid name");
}
- if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]+").matcher(identifier).matches()) {
+ if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches()) {
return alwaysQuote ? "\"" + identifier + "\"" : identifier;
}
if (identifier.matches("^\".+\"$")) {
@@ -1520,4 +1521,65 @@
throw new SQLException("Invalid name");
}
}
+
+ /**
+ * Retrieves whether {@code identifier} is a simple SQL identifier.
+ *
+ * @implSpec The default implementation uses the following criteria to
+ * determine a valid simple SQL identifier:
+ * <ul>
+ * <li>The string is not enclosed in double quotes</li>
+ * <li>The first character is an alphabetic character from a through z, or
+ * from A through Z</li>
+ * <li>The string only contains alphanumeric characters or the character
+ * "_"</li>
+ * <li>The string is between 1 and 128 characters in length inclusive</li>
+ * </ul>
+ *
+ * <blockquote>
+ * <table border = 1 cellspacing=0 cellpadding=5 >
+ * <caption>Examples of the conversion:</caption>
+ * <tr>
+ * <th>identifier</th>
+ * <th>Simple Identifier</th>
+ *
+ * <tr>
+ * <td align='center'>Hello</td>
+ * <td align='center'>true</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>G'Day</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>"Bruce Wayne"</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>GoodDay$</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>Hello"World</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * <tr>
+ * <td align='center'>"Hello"World"</td>
+ * <td align='center'>false</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * @implNote JDBC driver implementations may need to provide their own
+ * implementation of this method in order to meet the requirements of the
+ * underlying datasource.
+ * @param identifier a SQL identifier
+ * @return true if a simple SQL identifier, false otherwise
+ * @throws NullPointerException if identifier is {@code null}
+ * @throws SQLException if a database access error occurs
+ */
+ default boolean isSimpleIdentifier(String identifier) throws SQLException {
+ int len = identifier.length();
+ return len >= 1 && len <= 128
+ && Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
+ }
}
--- a/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/DataSource.java Wed Dec 02 09:34:55 2015 -0800
@@ -26,7 +26,10 @@
package javax.sql;
import java.sql.Connection;
+import java.sql.ConnectionBuilder;
import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.ShardingKeyBuilder;
import java.sql.Wrapper;
/**
@@ -106,4 +109,35 @@
*/
Connection getConnection(String username, String password)
throws SQLException;
+
+ // JDBC 4.3
+
+ /**
+ * Create a new {@code ConnectionBuilder} instance
+ * @implSpec
+ * The default implementation will throw a {@code SQLFeatureNotSupportedException}
+ * @return The ConnectionBuilder instance that was created
+ * @throws SQLException if an error occurs creating the builder
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see createConnectionBuilder
+ */
+ default ConnectionBuilder createConnectionBuilder() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createConnectionBuilder not implemented");
+ };
+
+ /**
+ * Create a new {@code ShardingKeyBuilder} instance
+ * @implSpec
+ * The default implementation will throw a {@code SQLFeatureNotSupportedException}
+ * @return The ShardingKeyBuilder instance that was created
+ * @throws SQLException if an error occurs creating the builder
+ * @throws SQLFeatureNotSupportedException if the driver does not support this method
+ * @since 1.9
+ * @see ShardingKeyBuilder
+ */
+ default ShardingKeyBuilder createShardingKeyBuilder()
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented");
+ };
}
--- a/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnection.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -22,40 +22,151 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package javax.sql;
import java.sql.*;
-
/**
- * An object that provides support for distributed
- * transactions. An <code>XAConnection</code> object may be enlisted
- * in a distributed transaction by means of an <code>XAResource</code> object.
- * A transaction manager, usually part of a middle tier server, manages an
- * <code>XAConnection</code> object through the <code>XAResource</code> object.
+ * An object that provides support for distributed transactions. An
+ * {@code XAConnection} object may be enlisted in a distributed transaction
+ * by means of an {@code XAResource} object. A transaction manager, usually
+ * part of a middle tier server, manages an {@code XAConnection} object
+ * through the {@code XAResource} object.
* <P>
- * An application programmer does not use this interface directly; rather,
- * it is used by a transaction manager working in the middle tier server.
+ * An application programmer does not use this interface directly; rather, it is
+ * used by a transaction manager working in the middle tier server.
*
* @since 1.4
*/
-
public interface XAConnection extends PooledConnection {
+ /**
+ * Retrieves an {@code XAResource} object that the transaction manager
+ * will use to manage this {@code XAConnection} object's participation
+ * in a distributed transaction.
+ *
+ * @return the {@code XAResource} object
+ * @exception SQLException if a database access error occurs
+ * @exception SQLFeatureNotSupportedException if the JDBC driver does not
+ * support this method
+ * @since 1.4
+ */
+ javax.transaction.xa.XAResource getXAResource() throws SQLException;
- /**
- * Retrieves an <code>XAResource</code> object that
- * the transaction manager will use
- * to manage this <code>XAConnection</code> object's participation in a
- * distributed transaction.
- *
- * @return the <code>XAResource</code> object
- * @exception SQLException if a database access error occurs
- * @exception SQLFeatureNotSupportedException if the JDBC driver does not support
- * this method
- * @since 1.4
- */
- javax.transaction.xa.XAResource getXAResource() throws SQLException;
+ // JDBC 4.3
+
+ /**
+ * Sets and validates the sharding keys for this connection.
+ *
+ * @implSpec The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ *
+ * @apiNote This method validates that the sharding keys are valid for the
+ * {@code Connection}. The timeout value indicates how long the driver
+ * should wait for the {@code Connection} to verify that the sharding key is
+ * valid before {@code setShardingKeyIfValid} returns false.
+ * @param shardingKey the sharding key to be validated against this
+ * connection
+ * @param superShardingKey the super sharding key to be validated against
+ * this connection. The super sharding key may be {@code null}.
+ * @param timeout time in seconds before which the validation process is
+ * expected to be completed, otherwise the validation process is aborted. A
+ * value of 0 indicates the validation process will not time out.
+ * @return true if the connection is valid and the sharding keys are valid
+ * and set on this connection; false if the sharding keys are not valid or
+ * the timeout period expires before the operation completes.
+ * @throws SQLException if an error occurs while performing this validation;
+ * the {@code shardingkey} is {@code null}; a {@code superSharedingKey} is specified
+ * without a {@code shardingKey}; this method is called on a closed
+ * {@code connection}; or the {@code timeout} value is less than 0.
+ * @throws SQLFeatureNotSupportedException if the driver does not support
+ * sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default boolean setShardingKeyIfValid(ShardingKey shardingKey,
+ ShardingKey superShardingKey, int timeout)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
+ }
- }
+ /**
+ * Sets and validates the sharding key for this connection.
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method validates that the sharding key is valid for the
+ * {@code Connection}. The timeout value indicates how long the driver
+ * should wait for the {@code Connection} to verify that the sharding key
+ * is valid before {@code setShardingKeyIfValid} returns false.
+ * @param shardingKey the sharding key to be validated against this connection
+ * @param timeout time in seconds before which the validation process is expected to
+ * be completed,else the validation process is aborted. A value of 0 indicates
+ * the validation process will not time out.
+ * @return true if the connection is valid and the sharding key is valid to be
+ * set on this connection; false if the sharding key is not valid or
+ * the timeout period expires before the operation completes.
+ * @throws SQLException if there is an error while performing this validation;
+ * this method is called on a closed {@code connection}; the {@code shardingkey}
+ * is {@code null}; or the {@code timeout} value is less than 0.
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default boolean setShardingKeyIfValid(ShardingKey shardingKey, int timeout)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKeyIfValid not implemented");
+ }
+
+ /**
+ * Specifies a shardingKey and superShardingKey to use with this Connection
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method sets the specified sharding keys but does not require a
+ * round trip to the database to validate that the sharding keys are valid
+ * for the {@code Connection}.
+ * @param shardingKey the sharding key to set on this connection.
+ * @param superShardingKey the super sharding key to set on this connection.
+ * The super sharding key may be {@code null}
+ * @throws SQLException if an error occurs setting the sharding keys;
+ * this method is called on a closed {@code connection};
+ * the {@code shardingkey} is {@code null}; or
+ * a {@code superSharedingKey} is specified without a {@code shardingKey}
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default void setShardingKey(ShardingKey shardingKey, ShardingKey superShardingKey)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
+ }
+
+ /**
+ * Specifies a shardingKey to use with this Connection
+ * @implSpec
+ * The default implementation will throw a
+ * {@code SQLFeatureNotSupportedException}.
+ * @apiNote
+ * This method sets the specified sharding key but does not require a
+ * round trip to the database to validate that the sharding key is valid
+ * for the {@code Connection}.
+ * @param shardingKey the sharding key to set on this connection.
+ * @throws SQLException if an error occurs setting the sharding key;
+ * this method is called on a closed {@code connection}; or the
+ * {@code shardkingKey} is {@code null}
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see ShardingKey
+ * @see ShardingKeyBuilder
+ */
+ default void setShardingKey(ShardingKey shardingKey)
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.sql/share/classes/javax/sql/XAConnectionBuilder.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,105 @@
+/*
+ * 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 javax.sql;
+
+import java.sql.SQLException;
+import java.sql.ShardingKey;
+
+/**
+ * A builder created from a {@code XADataSource} object,
+ * used to establish a connection to the database that the
+ * {@code data source} object represents. The connection
+ * properties that were specified for the {@code data source} are used as the
+ * default values by the {@code XAConnectionBuilder}.
+ * <p>The following example illustrates the use of {@code XAConnectionBuilder}
+ * to create a {@link XAConnection}:
+ *
+ * <pre>{@code
+ * DataSource ds = new MyDataSource();
+ * ShardingKey superShardingKey = ds.createShardingKeyBuilder()
+ * .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ * .build();
+ * ShardingKey shardingKey = ds.createShardingKeyBuilder()
+ * .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ * .build();
+ * XAConnection con = ds.createXAConnectionBuilder()
+ * .user("rafa")
+ * .password("tennis")
+ * .setShardingKey(shardingKey)
+ * .setSuperShardingKey(superShardingKey)
+ * .build();
+ * }</pre>
+ *
+ * @since 1.9
+ *
+ */
+public interface XAConnectionBuilder {
+
+ /**
+ * Specifies the username to be used when creating a connection
+ *
+ * @param username the database user on whose behalf the connection is being
+ * made
+ * @return the same {@code XAConnectionBuilder} instance
+ */
+ XAConnectionBuilder user(String username);
+
+ /**
+ * Specifies the password to be used when creating a connection
+ *
+ * @param password the password to use for this connection. May be {@code null}
+ * @return the same {@code XAConnectionBuilder} instance
+ */
+ XAConnectionBuilder password(String password);
+
+ /**
+ * Specifies a {@code shardingKey} to be used when creating a connection
+ *
+ * @param shardingKey the ShardingKey. May be {@code null}
+ * @return the same {@code XAConnectionBuilder} instance
+ * @see java.sql.ShardingKey
+ * @see java.sql.ShardingKeyBuilder
+ */
+ XAConnectionBuilder shardingKey(ShardingKey shardingKey);
+
+ /**
+ * Specifies a {@code superShardingKey} to be used when creating a connection
+ *
+ * @param superShardingKey the SuperShardingKey. May be {@code null}
+ * @return the same {@code XAConnectionBuilder} instance
+ * @see java.sql.ShardingKey
+ * @see java.sql.ShardingKeyBuilder
+ */
+ XAConnectionBuilder superShardingKey(ShardingKey superShardingKey);
+
+ /**
+ * Returns an instance of the object defined by this builder.
+ *
+ * @return The built object
+ * @throws java.sql.SQLException If an error occurs building the object
+ */
+ XAConnection build() throws SQLException;
+
+}
--- a/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/java.sql/share/classes/javax/sql/XADataSource.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -80,4 +80,35 @@
*/
XAConnection getXAConnection(String user, String password)
throws SQLException;
+
+ // JDBC 4.3
+
+ /**
+ * Creates a new {@code XAConnectionBuilder} instance
+ * @implSpec
+ * The default implementation will throw a {@code SQLFeatureNotSupportedException}.
+ * @return The ConnectionBuilder instance that was created
+ * @throws SQLException if an error occurs creating the builder
+ * @throws SQLFeatureNotSupportedException if the driver does not support sharding
+ * @since 1.9
+ * @see XAConnectionBuilder
+ */
+ default XAConnectionBuilder createXAConnectionBuilder() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createXAConnectionBuilder not implemented");
+ };
+
+ /**
+ * Creates a new {@code ShardingKeyBuilder} instance
+ * @implSpec
+ * The default implementation will throw a {@code SQLFeatureNotSupportedException}.
+ * @return The ShardingKeyBuilder instance that was created
+ * @throws SQLException if an error occurs creating the builder
+ * @throws SQLFeatureNotSupportedException if the driver does not support this method
+ * @since 1.9
+ * @see ShardingKeyBuilder
+ */
+ default ShardingKeyBuilder createShardingKeyBuilder()
+ throws SQLException {
+ throw new SQLFeatureNotSupportedException("createShardingKeyBuilder not implemented");
+ };
}
--- a/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/KeyStore.java Wed Dec 02 09:34:55 2015 -0800
@@ -389,10 +389,22 @@
}
}
+ X509Certificate[] xchain;
+ if (chain != null) {
+ if (chain instanceof X509Certificate[]) {
+ xchain = (X509Certificate[]) chain;
+ } else {
+ xchain = new X509Certificate[chain.length];
+ System.arraycopy(chain, 0, xchain, 0, chain.length);
+ }
+ } else {
+ xchain = null;
+ }
+
if (! found) {
entry =
//TODO new KeyEntry(alias, key, (X509Certificate[]) chain);
- new KeyEntry(alias, null, (X509Certificate[]) chain);
+ new KeyEntry(alias, null, xchain);
entries.add(entry);
}
@@ -400,7 +412,7 @@
try {
entry.setPrivateKey((RSAPrivateCrtKey) key);
- entry.setCertificateChain((X509Certificate[]) chain);
+ entry.setCertificateChain(xchain);
} catch (CertificateException ce) {
throw new KeyStoreException(ce);
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Dec 02 09:34:55 2015 -0800
@@ -150,6 +150,7 @@
private Date expireDate = new Date(0L); // used in noTimestamp warning
// Severe warnings
+ private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
private boolean hasExpiredCert = false;
private boolean notYetValidCert = false;
private boolean chainNotValidated = false;
@@ -159,6 +160,9 @@
private boolean badKeyUsage = false;
private boolean badExtendedKeyUsage = false;
private boolean badNetscapeCertType = false;
+ private boolean signerSelfSigned = false;
+
+ private Throwable chainNotValidatedReason = null;
CertificateFactory certificateFactory;
CertPathValidator validator;
@@ -243,7 +247,7 @@
if (strict) {
int exitCode = 0;
- if (chainNotValidated || hasExpiredCert || notYetValidCert) {
+ if (weakAlg != 0 || chainNotValidated || hasExpiredCert || notYetValidCert || signerSelfSigned) {
exitCode |= 4;
}
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType) {
@@ -780,6 +784,12 @@
if (man == null)
System.out.println(rb.getString("no.manifest."));
+ // If signer is a trusted cert or private entry in user's own
+ // keystore, it can be self-signed.
+ if (!aliasNotInStore) {
+ signerSelfSigned = false;
+ }
+
if (!anySigned) {
System.out.println(rb.getString(
"jar.is.unsigned.signatures.missing.or.not.parsable."));
@@ -788,7 +798,7 @@
boolean errorAppeared = false;
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
notYetValidCert || chainNotValidated || hasExpiredCert ||
- hasUnsignedEntry ||
+ hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) ||
aliasNotInStore || notSignedByAlias) {
if (strict) {
@@ -803,6 +813,12 @@
warningAppeared = true;
}
+ if (weakAlg != 0) {
+ // In fact, jarsigner verification did not catch this
+ // since it has not read the JarFile content itself.
+ // Everything is done with JarFile API.
+ }
+
if (badKeyUsage) {
System.out.println(
rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
@@ -832,8 +848,9 @@
}
if (chainNotValidated) {
- System.out.println(
- rb.getString("This.jar.contains.entries.whose.certificate.chain.is.not.validated."));
+ System.out.println(String.format(
+ rb.getString("This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1"),
+ chainNotValidatedReason.getLocalizedMessage()));
}
if (notSignedByAlias) {
@@ -844,6 +861,11 @@
if (aliasNotInStore) {
System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore."));
}
+
+ if (signerSelfSigned) {
+ System.out.println(rb.getString(
+ "This.jar.contains.entries.whose.signer.certificate.is.self.signed."));
+ }
} else {
System.out.println(rb.getString("jar.verified."));
}
@@ -1074,7 +1096,25 @@
}
void signJar(String jarName, String alias)
- throws Exception {
+ throws Exception {
+
+ DisabledAlgorithmConstraints dac =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
+
+ if (digestalg != null && !dac.permits(
+ Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
+ weakAlg |= 1;
+ }
+ if (tSADigestAlg != null && !dac.permits(
+ Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
+ weakAlg |= 4;
+ }
+ if (sigalg != null && !dac.permits(
+ Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
+ weakAlg |= 2;
+ }
+
boolean aliasUsed = false;
X509Certificate tsaCert = null;
@@ -1255,8 +1295,8 @@
}
boolean warningAppeared = false;
- if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
- notYetValidCert || chainNotValidated || hasExpiredCert) {
+ if (weakAlg != 0 || badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
+ notYetValidCert || chainNotValidated || hasExpiredCert || signerSelfSigned) {
if (strict) {
System.out.println(rb.getString("jar.signed.with.signer.errors."));
System.out.println();
@@ -1292,8 +1332,31 @@
}
if (chainNotValidated) {
+ System.out.println(String.format(
+ rb.getString("The.signer.s.certificate.chain.is.not.validated.reason.1"),
+ chainNotValidatedReason.getLocalizedMessage()));
+ }
+
+ if (signerSelfSigned) {
System.out.println(
- rb.getString("The.signer.s.certificate.chain.is.not.validated."));
+ rb.getString("The.signer.s.certificate.is.self.signed."));
+ }
+
+ if ((weakAlg & 1) == 1) {
+ System.out.println(String.format(
+ rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+ digestalg, "-digestalg"));
+ }
+
+ if ((weakAlg & 2) == 2) {
+ System.out.println(String.format(
+ rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+ sigalg, "-sigalg"));
+ }
+ if ((weakAlg & 4) == 4) {
+ System.out.println(String.format(
+ rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
+ tSADigestAlg, "-tsadigestalg"));
}
} else {
System.out.println(rb.getString("jar.signed."));
@@ -1377,10 +1440,15 @@
// No more warning, we alreay have hasExpiredCert or notYetValidCert
} else {
chainNotValidated = true;
+ chainNotValidatedReason = e;
sb.append(tab).append(rb.getString(".CertPath.not.validated."))
.append(e.getLocalizedMessage()).append("]\n"); // TODO
}
}
+ if (certs.size() == 1
+ && KeyStoreUtil.isSelfSigned((X509Certificate)certs.get(0))) {
+ signerSelfSigned = true;
+ }
String result = sb.toString();
cacheForSignerInfo.put(signer, result);
return result;
@@ -1645,12 +1713,17 @@
if (e.getCause() != null &&
(e.getCause() instanceof CertificateExpiredException ||
e.getCause() instanceof CertificateNotYetValidException)) {
- // No more warning, we alreay have hasExpiredCert or notYetValidCert
+ // No more warning, we already have hasExpiredCert or notYetValidCert
} else {
chainNotValidated = true;
+ chainNotValidatedReason = e;
}
}
+ if (KeyStoreUtil.isSelfSigned(certChain[0])) {
+ signerSelfSigned = true;
+ }
+
try {
if (!token && keypass == null)
key = store.getKey(alias, storepass);
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Dec 02 09:34:55 2015 -0800
@@ -212,6 +212,8 @@
"This jar contains entries whose signer certificate will expire within six months. "},
{"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid.",
"This jar contains entries whose signer certificate is not yet valid. "},
+ {"This.jar.contains.entries.whose.signer.certificate.is.self.signed.",
+ "This jar contains entries whose signer certificate is self-signed."},
{"Re.run.with.the.verbose.option.for.more.details.",
"Re-run with the -verbose option for more details."},
{"Re.run.with.the.verbose.and.certs.options.for.more.details.",
@@ -236,10 +238,14 @@
"This jar contains entries whose signer certificate's NetscapeCertType extension doesn't allow code signing."},
{".{0}.extension.does.not.support.code.signing.",
"[{0} extension does not support code signing]"},
- {"The.signer.s.certificate.chain.is.not.validated.",
- "The signer's certificate chain is not validated."},
- {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.",
- "This jar contains entries whose certificate chain is not validated."},
+ {"The.signer.s.certificate.chain.is.not.validated.reason.1",
+ "The signer's certificate chain is not validated. Reason: %s"},
+ {"The.signer.s.certificate.is.self.signed.",
+ "The signer's certificate is self-signed."},
+ {"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
+ "The %1$s algorithm specified for the %2$s option is considered a security risk."},
+ {"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
+ "This jar contains entries whose certificate chain is not validated. Reason: %s"},
{"no.timestamp.signing",
"No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
{"no.timestamp.verifying",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,1 @@
+sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import sun.jvmstat.monitor.*;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.io.IOException;
+
+/**
+ * Remote Interface for discovering and attaching to remote
+ * monitorable Java Virtual Machines.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteHost extends Remote {
+
+ /**
+ * Remote method to attach to a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param vmid The identifier for the target virtual machine.
+ * @return RemoteVm - A remote object for accessing the remote Java
+ * Virtual Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ *
+ */
+ RemoteVm attachVm(int vmid, String mode) throws RemoteException,
+ MonitorException;
+
+ /**
+ * Remote method to detach from a remote HotSpot Java Virtual Machine
+ * identified by <code>vmid</code>.
+ *
+ * @param rvm The remote object for the target Java Virtual
+ * Machine.
+ *
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
+
+ /**
+ * Get a list of Local Virtual Machine Identifiers for the active
+ * Java Virtual Machine the remote system. A Local Virtual Machine
+ * Identifier is also known as an <em>lvmid</em>.
+ *
+ * @return int[] - A array of <em>lvmid</em>s.
+ * @throws MonitorException Thrown when any other error is encountered
+ * while communicating with the target virtual
+ * machine.
+ * @throws RemoteException
+ */
+ int[] activeVms() throws RemoteException, MonitorException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.monitor.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * Interface for accessing the instrumentation exported by a
+ * Java Virtual Machine running on a remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public interface RemoteVm extends Remote {
+
+ /**
+ * Interface to get the bytes associated with the instrumentation
+ * for the remote Java Virtual Machine.
+ *
+ * @return byte[] - a byte array containing the current bytes
+ * for the instrumentation exported by the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ byte[] getBytes() throws RemoteException;
+
+ /**
+ * Interface to get the size of the instrumentation buffer
+ * for the target Java Virtual Machine.
+ *
+ * @return int - the size of the instrumentation buffer for the
+ * remote Java Virtual Machine.
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getCapacity() throws RemoteException;
+
+ /**
+ * Interface to return the Local Virtual Machine Identifier for
+ * the remote Java Virtual Machine. The Local Virtual Machine
+ * Identifier is also know as the <em>lvmid</em>.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ int getLocalVmId() throws RemoteException;
+
+ /**
+ * Interface to detach from the remote Java Virtual Machine.
+ *
+ * @throws RemoteException Thrown on any communication error
+ */
+ void detach() throws RemoteException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/monitor/remote/package.html Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,39 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ 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.
+
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides interfaces supporting remote monitoring for instrumented
+HotSpot Java Virtual Machines.
+</p>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.rmi.*;
+import java.util.HashMap;
+
+/**
+ * Concrete implementation of the MonitoredHost interface for the
+ * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class MonitoredHostProvider extends MonitoredHost {
+ private static final String serverName = "/JStatRemoteHost";
+ private static final int DEFAULT_POLLING_INTERVAL = 1000;
+
+ private ArrayList<HostListener> listeners;
+ private NotifierTask task;
+ private HashSet<Integer> activeVms;
+ private RemoteVmManager vmManager;
+ private RemoteHost remoteHost;
+ private Timer timer;
+
+ /**
+ * Create a MonitoredHostProvider instance using the given HostIdentifier.
+ *
+ * @param hostId the host identifier for this MonitoredHost
+ * @throws MonitorException Thrown on any error encountered while
+ * communicating with the remote host.
+ */
+ public MonitoredHostProvider(HostIdentifier hostId)
+ throws MonitorException {
+ this.hostId = hostId;
+ this.listeners = new ArrayList<HostListener>();
+ this.interval = DEFAULT_POLLING_INTERVAL;
+ this.activeVms = new HashSet<Integer>();
+
+ String rmiName;
+ String sn = serverName;
+ String path = hostId.getPath();
+
+ if ((path != null) && (path.length() > 0)) {
+ sn = path;
+ }
+
+ if (hostId.getPort() != -1) {
+ rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
+ } else {
+ rmiName = "rmi://" + hostId.getHost() + sn;
+ }
+
+ try {
+ remoteHost = (RemoteHost)Naming.lookup(rmiName);
+
+ } catch (RemoteException e) {
+ /*
+ * rmi registry not available
+ *
+ * Access control exceptions, where the rmi server refuses a
+ * connection based on policy file configuration, come through
+ * here on the client side. Unfortunately, the RemoteException
+ * doesn't contain enough information to determine the true cause
+ * of the exception. So, we have to output a rather generic message.
+ */
+ String message = "RMI Registry not available at "
+ + hostId.getHost();
+
+ if (hostId.getPort() == -1) {
+ message = message + ":"
+ + java.rmi.registry.Registry.REGISTRY_PORT;
+ } else {
+ message = message + ":" + hostId.getPort();
+ }
+
+ if (e.getMessage() != null) {
+ throw new MonitorException(message + "\n" + e.getMessage(), e);
+ } else {
+ throw new MonitorException(message, e);
+ }
+
+ } catch (NotBoundException e) {
+ // no server with given name
+ String message = e.getMessage();
+ if (message == null) message = rmiName;
+ throw new MonitorException("RMI Server " + message
+ + " not available", e);
+ } catch (MalformedURLException e) {
+ // this is a programming problem
+ e.printStackTrace();
+ throw new IllegalArgumentException("Malformed URL: " + rmiName);
+ }
+ this.vmManager = new RemoteVmManager(remoteHost);
+ this.timer = new Timer(true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid)
+ throws MonitorException {
+ return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
+ throws MonitorException {
+ VmIdentifier nvmid = null;
+ try {
+ nvmid = hostId.resolve(vmid);
+ RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
+ vmid.getMode());
+ RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
+ interval);
+ rmvm.attach();
+ return rmvm;
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception attaching to "
+ + nvmid.toString(), e);
+ } catch (URISyntaxException e) {
+ /*
+ * the VmIdentifier is expected to be a valid and should resolve
+ * easonably against the host identifier. A URISyntaxException
+ * here is most likely a programming error.
+ */
+ throw new IllegalArgumentException("Malformed URI: "
+ + vmid.toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach(MonitoredVm vm) throws MonitorException {
+ RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
+ rmvm.detach();
+ try {
+ remoteHost.detachVm(rmvm.getRemoteVm());
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Remote Exception detaching from "
+ + vm.getVmIdentifier().toString(), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addHostListener(HostListener listener) {
+ synchronized(listeners) {
+ listeners.add(listener);
+ if (task == null) {
+ task = new NotifierTask();
+ timer.schedule(task, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeHostListener(HostListener listener) {
+ /*
+ * XXX: if a disconnect method is added, make sure it calls
+ * this method to unregister this object from the watcher. otherwise,
+ * an unused MonitoredHostProvider instance may go uncollected.
+ */
+ synchronized(listeners) {
+ listeners.remove(listener);
+ if (listeners.isEmpty() && (task != null)) {
+ task.cancel();
+ task = null;
+ }
+ }
+ }
+
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (task != null) {
+ task.cancel();
+ NotifierTask oldTask = task;
+ task = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldTask, task,
+ oldInterval, newInterval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ return vmManager.activeVms();
+ }
+
+ /**
+ * Fire VmStatusChangeEvent events to HostListener objects
+ *
+ * @param active Set of Integer objects containing the local
+ * Vm Identifiers of the active JVMs
+ * @param started Set of Integer objects containing the local
+ * Vm Identifiers of new JVMs started since last
+ * interval.
+ * @param terminated Set of Integer objects containing the local
+ * Vm Identifiers of terminated JVMs since last
+ * interval.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
+ Set<Integer> terminated) {
+ ArrayList<HostListener> registered = null;
+ VmStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new VmStatusChangeEvent(this, active, started, terminated);
+ }
+ l.vmStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire hostDisconnectEvent events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireDisconnectedEvents() {
+ ArrayList<HostListener> registered = null;
+ HostEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ HostListener l = i.next();
+ if (ev == null) {
+ ev = new HostEvent(this);
+ }
+ l.disconnected(ev);
+ }
+ }
+
+ /**
+ * class to poll the remote machine and generate local event notifications.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+
+ // save the last set of active JVMs
+ Set<Integer> lastActiveVms = activeVms;
+
+ try {
+ // get the current set of active JVMs
+ activeVms = (HashSet<Integer>)vmManager.activeVms();
+
+ } catch (MonitorException e) {
+ // XXX: use logging api
+ System.err.println("MonitoredHostProvider: polling task "
+ + "caught MonitorException:");
+ e.printStackTrace();
+
+ // mark the HostManager as errored and notify listeners
+ setLastException(e);
+ fireDisconnectedEvents();
+ }
+
+ if (activeVms.isEmpty()) {
+ return;
+ }
+
+ Set<Integer> startedVms = new HashSet<>();
+ Set<Integer> terminatedVms = new HashSet<>();
+
+ for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
+ Integer vmid = i.next();
+ if (!lastActiveVms.contains(vmid)) {
+ // a new file has been detected, add to set
+ startedVms.add(vmid);
+ }
+ }
+
+ for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
+ /* empty */ ) {
+ Integer o = i.next();
+ if (!activeVms.contains(o)) {
+ // JVM has terminated, remove it from the active list
+ terminatedVms.add(o);
+ }
+ }
+
+ if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
+ fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.HostIdentifier;
+import sun.jvmstat.monitor.MonitorException;
+import sun.jvmstat.monitor.MonitoredHost;
+import sun.jvmstat.monitor.MonitoredHostService;
+
+public final class MonitoredHostRmiService implements MonitoredHostService {
+
+ @Override
+ public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
+ return new MonitoredHostProvider(hostId);
+ }
+
+ @Override
+ public String getScheme() {
+ return "rmi";
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import java.nio.ByteBuffer;
+
+/**
+ * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
+ * protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class is responsible for acquiring the instrumentation buffer
+ * data for a remote target HotSpot Java Virtual Machine.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class PerfDataBuffer extends AbstractPerfDataBuffer {
+
+ private RemoteVm rvm;
+
+ /**
+ * Create a PerfDataBuffer instance for accessing the specified
+ * instrumentation buffer.
+ *
+ * @param rvm the proxy to the remote MonitredVm object
+ * @param lvmid the local Java Virtual Machine Identifier of the
+ * remote target.
+ *
+ * @throws MonitorException
+ */
+ public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
+
+ this.rvm = rvm;
+ try {
+ ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
+ sample(buffer);
+ createPerfDataBuffer(buffer, lvmid);
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Could not read data for remote JVM "
+ + lvmid, e);
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * the local byte buffer.
+ *
+ * @param buffer the buffer to receive the copy of the remote
+ * instrumentation buffer.
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample(ByteBuffer buffer) throws RemoteException {
+ assert buffer != null;
+ assert rvm != null;
+ synchronized(buffer) {
+ buffer.clear();
+ buffer.put(rvm.getBytes());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+import sun.jvmstat.perfdata.monitor.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.rmi.*;
+
+/**
+ * Concrete implementation of the AbstractMonitoredVm class for the
+ * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
+ * <p>
+ * This class provides the ability to acquire to the instrumentation buffer
+ * of a live, remote target Java Virtual Machine through an RMI server.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteMonitoredVm extends AbstractMonitoredVm {
+
+ private ArrayList<VmListener> listeners;
+ private NotifierTask notifierTask;
+ private SamplerTask samplerTask;
+ private Timer timer;
+
+ private RemoteVm rvm;
+ private ByteBuffer updateBuffer;
+
+ /**
+ * Create a RemoteMonitoredVm instance.
+ *
+ * @param rvm the proxy to the remote MonitoredVm instance.
+ * @param vmid the vm identifier specifying the remot target JVM
+ * @param timer the timer used to run polling tasks
+ * @param interval the sampling interval
+ */
+ public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
+ Timer timer, int interval)
+ throws MonitorException {
+ super(vmid, interval);
+ this.rvm = rvm;
+ pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
+ this.listeners = new ArrayList<VmListener>();
+ this.timer = timer;
+ }
+
+ /**
+ * Method to attach to the remote MonitoredVm.
+ */
+ public void attach() throws MonitorException {
+ updateBuffer = pdb.getByteBuffer().duplicate();
+
+ // if continuous sampling is requested, register with the sampler thread
+ if (interval > 0) {
+ samplerTask = new SamplerTask();
+ timer.schedule(samplerTask, 0, interval);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void detach() {
+ try {
+ if (interval > 0) {
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ samplerTask = null;
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ sample();
+ }
+ } catch (RemoteException e) {
+ // XXX: - use logging api? throw an exception instead?
+ System.err.println("Could not read data for remote JVM " + vmid);
+ e.printStackTrace();
+
+ } finally {
+ super.detach();
+ }
+ }
+
+ /**
+ * Get a copy of the remote instrumentation buffer.
+ *<p>
+ * The data in the remote instrumentation buffer is copied into
+ * a local byte buffer.
+ *
+ * @throws RemoteException Thrown on any communications errors with
+ * the remote system.
+ */
+ public void sample() throws RemoteException {
+ assert updateBuffer != null;
+ ((PerfDataBuffer)pdb).sample(updateBuffer);
+ }
+
+ /**
+ * Get the proxy to the remote MonitoredVm.
+ *
+ * @return RemoteVm - the proxy to the remote MonitoredVm.
+ */
+ public RemoteVm getRemoteVm() {
+ return rvm;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.add(l);
+ if (notifierTask == null) {
+ notifierTask = new NotifierTask();
+ timer.schedule(notifierTask, 0, interval);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeVmListener(VmListener l) {
+ synchronized(listeners) {
+ listeners.remove(l);
+ if (listeners.isEmpty() && (notifierTask != null)) {
+ notifierTask.cancel();
+ notifierTask = null;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setInterval(int newInterval) {
+ synchronized(listeners) {
+ if (newInterval == interval) {
+ return;
+ }
+
+ int oldInterval = interval;
+ super.setInterval(newInterval);
+
+ if (samplerTask != null) {
+ samplerTask.cancel();
+ SamplerTask oldSamplerTask = samplerTask;
+ samplerTask = new SamplerTask();
+ CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
+ samplerTask, oldInterval,
+ newInterval);
+ }
+ if (notifierTask != null) {
+ notifierTask.cancel();
+ NotifierTask oldNotifierTask = notifierTask;
+ notifierTask = new NotifierTask();
+ CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
+ notifierTask, oldInterval,
+ newInterval);
+ }
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ *
+ * @param inserted List of Monitor objects inserted.
+ * @param removed List of Monitor objects removed.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
+ ArrayList<VmListener> registered = null;
+ MonitorStatusChangeEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new MonitorStatusChangeEvent(this, inserted, removed);
+ }
+ l.monitorStatusChanged(ev);
+ }
+ }
+
+ /**
+ * Fire MonitoredVmStructureChanged events.
+ */
+ @SuppressWarnings("unchecked") // Cast of result of clone
+ void fireMonitorsUpdatedEvents() {
+ ArrayList<VmListener> registered = null;
+ VmEvent ev = null;
+
+ synchronized(listeners) {
+ registered = (ArrayList)listeners.clone();
+ }
+
+ for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
+ VmListener l = i.next();
+ if (ev == null) {
+ ev = new VmEvent(this);
+ }
+ l.monitorsUpdated(ev);
+ }
+ }
+
+ /*
+ * Timer Tasks. There are two separate timer tasks here. The SamplerTask
+ * is active whenever we are attached to the remote JVM with a periodic
+ * sampling interval > 0. The NotifierTask is only active if a VmListener
+ * has registered with this RemoteMonitoredVm instance. Also, in the future
+ * we may want to run these tasks at different intervals. Currently,
+ * they run at the same interval and some significant work may
+ * need to be done to complete the separation of these two intervals.
+ */
+
+ /**
+ * Class to periodically check the state of the defined monitors
+ * for the remote MonitoredVm instance and to notify listeners of
+ * any detected changes.
+ */
+ private class NotifierTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ MonitorStatus status = getMonitorStatus();
+
+ List<Monitor> inserted = status.getInserted();
+ List<Monitor> removed = status.getRemoved();
+
+ if (!inserted.isEmpty() || !removed.isEmpty()) {
+ fireMonitorStatusChangedEvents(inserted, removed);
+ }
+ } catch (MonitorException e) {
+ // XXX: use logging api? fire disconnect events? mark errored?
+ // fireDisconnectedEvents();
+ System.err.println("Exception updating monitors for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ // XXX: should we cancle the notifierTask here?
+ // this.cancel();
+ }
+ }
+ }
+
+ /**
+ * Class to periodically sample the remote instrumentation byte buffer
+ * and refresh the local copy. Registered listeners are notified of
+ * the completion of a sampling event.
+ */
+ private class SamplerTask extends CountedTimerTask {
+ public void run() {
+ super.run();
+ try {
+ sample();
+ fireMonitorsUpdatedEvents();
+
+ } catch (RemoteException e) {
+ // XXX: use logging api, mark vm as errored.
+ System.err.println("Exception taking sample for "
+ + getVmIdentifier());
+ e.printStackTrace();
+ this.cancel();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.jvmstat.perfdata.monitor.protocol.rmi;
+
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.rmi.RemoteException;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Class for managing the RemoteMonitoredVm instances on a remote system.
+ * <p>
+ * This class is responsible for the mechanism that detects the active
+ * HotSpot Java Virtual Machines on the remote host and possibly for a
+ * specific user. The ability to detect all possible HotSpot Java Virtual
+ * Machines on the remote host may be limited by the permissions of the
+ * principal running the RMI server application on the remote host.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmManager {
+
+ private RemoteHost remoteHost;
+ private String user;
+
+ /**
+ * Creates a RemoteVmManager instance for the remote system.
+ * <p>
+ * Manages RemoteMonitordVm instances for which the principal
+ * running the remote server has appropriate permissions.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ */
+ public RemoteVmManager(RemoteHost remoteHost) {
+ this(remoteHost, null);
+ }
+
+ /**
+ * Creates a RemoteVmManager instance for the given user.
+ * <p>
+ * Manages RemoteMonitoredVm instances for all remote Java Virtual
+ * machines owned by the specified user on the remote system. The
+ * RMI server on the remote system must have the appropriate permissions
+ * to access the named users Java Virtual Machines.
+ *
+ * @param remoteHost the remote proxy object to the RMI server on
+ * the remote system.
+ * @param user the name of the user
+ */
+ public RemoteVmManager(RemoteHost remoteHost, String user) {
+ this.user = user;
+ this.remoteHost = remoteHost;
+ }
+
+ /**
+ * Return the current set of monitorable Java Virtual Machines.
+ * <p>
+ * The set returned by this method depends on the user name passed
+ * to the constructor. If no user name was specified, then this
+ * method will return all candidate JVMs on the system. Otherwise,
+ * only the JVMs for the given user will be returned. This assumes
+ * that the RMI server process has the appropriate permissions to
+ * access the target set of JVMs.
+ *
+ * @return Set - the Set of monitorable Java Virtual Machines
+ */
+ public Set<Integer> activeVms() throws MonitorException {
+ int[] active = null;
+
+ try {
+ active = remoteHost.activeVms();
+
+ } catch (RemoteException e) {
+ throw new MonitorException("Error communicating with remote host: "
+ + e.getMessage(), e);
+ }
+
+ Set<Integer> activeSet = new HashSet<Integer>(active.length);
+
+ for (int i = 0; i < active.length; i++) {
+ activeSet.add(active[i]);
+ }
+
+ return activeSet;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,47 @@
+<!doctype html public "-//IETF//DTD HTML/EN">
+<html>
+<head>
+<!--
+
+
+ Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ 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.
+
+-->
+</head>
+<body bgcolor="white">
+<p>
+Provides the implementation classes for the <em>rmi:</em> protocol for
+the HotSpot PerfData instrumentation buffer monitoring implementation.
+</p>
+<p>
+The <em>rmi:</em> protocol is the default protocol for the PerfData
+implementation when a hostname is specified as part of a HostIdentifier
+or VMIdentifier. It communicates with an RMI server on the remote machine
+that provides functions to get a list of available Java Virtual Machines
+and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
+The RMI server may or may not use the PerfData implementation on the
+remote host to acquire this information. The <em>jstatd</em> server
+provides a PerfData implementation of the RMI server.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/Jstatd.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2004, 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 sun.tools.jstatd;
+
+import java.rmi.*;
+import java.rmi.server.*;
+import java.rmi.registry.Registry;
+import java.rmi.registry.LocateRegistry;
+import java.net.MalformedURLException;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Application providing remote access to the jvmstat instrumentation
+ * exported by local Java Virtual Machine processes. Remote access is
+ * provided through an RMI interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class Jstatd {
+
+ private static Registry registry;
+ private static int port = -1;
+ private static boolean startRegistry = true;
+
+ private static void printUsage() {
+ System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
+ }
+
+ static void bind(String name, RemoteHostImpl remoteHost)
+ throws RemoteException, MalformedURLException, Exception {
+
+ try {
+ Naming.rebind(name, remoteHost);
+ } catch (java.rmi.ConnectException e) {
+ /*
+ * either the registry is not running or we cannot contact it.
+ * start an internal registry if requested.
+ */
+ if (startRegistry && registry == null) {
+ int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
+ registry = LocateRegistry.createRegistry(localport);
+ bind(name, remoteHost);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ @SuppressWarnings("deprecation") // Use of RMISecurityManager
+ public static void main(String[] args) {
+ String rminame = null;
+ int argc = 0;
+
+ for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
+ String arg = args[argc];
+
+ if (arg.compareTo("-nr") == 0) {
+ startRegistry = false;
+ } else if (arg.startsWith("-p")) {
+ if (arg.compareTo("-p") != 0) {
+ port = Integer.parseInt(arg.substring(2));
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ port = Integer.parseInt(args[argc]);
+ }
+ } else if (arg.startsWith("-n")) {
+ if (arg.compareTo("-n") != 0) {
+ rminame = arg.substring(2);
+ } else {
+ argc++;
+ if (argc >= args.length) {
+ printUsage();
+ System.exit(1);
+ }
+ rminame = args[argc];
+ }
+ } else {
+ printUsage();
+ System.exit(1);
+ }
+ }
+
+ if (argc < args.length) {
+ printUsage();
+ System.exit(1);
+ }
+
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new RMISecurityManager());
+ }
+
+ StringBuilder name = new StringBuilder();
+
+ if (port >= 0) {
+ name.append("//:").append(port);
+ }
+
+ if (rminame == null) {
+ rminame = "JStatRemoteHost";
+ }
+
+ name.append("/").append(rminame);
+
+ try {
+ // use 1.5.0 dynamically generated subs.
+ System.setProperty("java.rmi.server.ignoreSubClasses", "true");
+ RemoteHostImpl remoteHost = new RemoteHostImpl();
+ RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
+ remoteHost, 0);
+ bind(name.toString(), remoteHost);
+ System.out.println("jstatd started (bound to " + name.toString() + ")");
+ System.out.flush();
+ } catch (MalformedURLException e) {
+ if (rminame != null) {
+ System.out.println("Bad RMI server name: " + rminame);
+ } else {
+ System.out.println("Bad RMI URL: " + name);
+ }
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (java.rmi.ConnectException e) {
+ // could not attach to or create a registry
+ System.out.println("Could not contact RMI registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (RemoteException e) {
+ System.out.println("Could not bind " + name + " to RMI Registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (Exception e) {
+ System.out.println("Could not create remote object");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteHostImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+import java.rmi.*;
+import java.rmi.server.*;
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.event.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteHost interface for the HotSpot
+ * PerfData <em>rmi:</em> protocol.
+ * <p>
+ * This class provides remote access to the instrumentation exported
+ * by HotSpot Java Virtual Machines through the PerfData shared memory
+ * interface.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteHostImpl implements RemoteHost, HostListener {
+
+ private MonitoredHost monitoredHost;
+ private Set<Integer> activeVms;
+
+ public RemoteHostImpl() throws MonitorException {
+ try {
+ monitoredHost = MonitoredHost.getMonitoredHost("localhost");
+ } catch (URISyntaxException e) { }
+
+ activeVms = monitoredHost.activeVms();
+ monitoredHost.addHostListener(this);
+ }
+
+ public RemoteVm attachVm(int lvmid, String mode)
+ throws RemoteException, MonitorException {
+ Integer v = lvmid;
+ RemoteVm stub = null;
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("local://").append(lvmid).append("@localhost");
+ if (mode != null) {
+ sb.append("?mode=").append(mode);
+ }
+
+ String vmidStr = sb.toString();
+
+ try {
+ VmIdentifier vmid = new VmIdentifier(vmidStr);
+ MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
+ RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
+ stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
+ }
+ catch (URISyntaxException e) {
+ throw new RuntimeException("Malformed VmIdentifier URI: "
+ + vmidStr, e);
+ }
+ return stub;
+ }
+
+ public void detachVm(RemoteVm rvm) throws RemoteException {
+ rvm.detach();
+ }
+
+ public int[] activeVms() throws MonitorException {
+ Object[] vms = null;
+ int[] vmids = null;
+
+ vms = monitoredHost.activeVms().toArray();
+ vmids = new int[vms.length];
+
+ for (int i = 0; i < vmids.length; i++) {
+ vmids[i] = ((Integer)vms[i]).intValue();
+ }
+ return vmids;
+ }
+
+ public void vmStatusChanged(VmStatusChangeEvent ev) {
+ synchronized(this.activeVms) {
+ activeVms.retainAll(ev.getActive());
+ }
+ }
+
+ public void disconnected(HostEvent ev) {
+ // we only monitor the local host, so this event shouldn't occur.
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jvmstat.rmi/share/classes/sun/tools/jstatd/RemoteVmImpl.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.tools.jstatd;
+
+import sun.jvmstat.monitor.*;
+import sun.jvmstat.monitor.remote.*;
+
+/**
+ * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
+ * shared memory implementation of the jvmstat monitoring APIs. This class
+ * providing remote access to the instrumentation exported by a local HotSpot
+ * Java Virtual Machine. The instrumentation buffer is shipped in whole to
+ * the remote machine, which is responsible for parsing and provide access
+ * to the contained data.
+ *
+ * @author Brian Doherty
+ * @since 1.5
+ */
+public class RemoteVmImpl implements RemoteVm {
+
+ private BufferedMonitoredVm mvm;
+
+ RemoteVmImpl(BufferedMonitoredVm mvm) {
+ this.mvm = mvm;
+ }
+
+ public byte[] getBytes() {
+ return mvm.getBytes();
+ }
+
+ public int getCapacity() {
+ return mvm.getCapacity();
+ }
+
+ public void detach() {
+ mvm.detach();
+ }
+
+ public int getLocalVmId() {
+ return mvm.getVmIdentifier().getLocalVmId();
+ }
+}
--- a/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/jdk.jvmstat/share/classes/META-INF/services/sun.jvmstat.monitor.MonitoredHostService Wed Dec 02 09:34:55 2015 -0800
@@ -1,3 +1,2 @@
sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService
sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService
-sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteHost.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import sun.jvmstat.monitor.*;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.io.IOException;
-
-/**
- * Remote Interface for discovering and attaching to remote
- * monitorable Java Virtual Machines.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteHost extends Remote {
-
- /**
- * Remote method to attach to a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param vmid The identifier for the target virtual machine.
- * @return RemoteVm - A remote object for accessing the remote Java
- * Virtual Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- *
- */
- RemoteVm attachVm(int vmid, String mode) throws RemoteException,
- MonitorException;
-
- /**
- * Remote method to detach from a remote HotSpot Java Virtual Machine
- * identified by <code>vmid</code>.
- *
- * @param rvm The remote object for the target Java Virtual
- * Machine.
- *
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- void detachVm(RemoteVm rvm) throws RemoteException, MonitorException;
-
- /**
- * Get a list of Local Virtual Machine Identifiers for the active
- * Java Virtual Machine the remote system. A Local Virtual Machine
- * Identifier is also known as an <em>lvmid</em>.
- *
- * @return int[] - A array of <em>lvmid</em>s.
- * @throws MonitorException Thrown when any other error is encountered
- * while communicating with the target virtual
- * machine.
- * @throws RemoteException
- */
- int[] activeVms() throws RemoteException, MonitorException;
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/RemoteVm.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.monitor.remote;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Interface for accessing the instrumentation exported by a
- * Java Virtual Machine running on a remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public interface RemoteVm extends Remote {
-
- /**
- * Interface to get the bytes associated with the instrumentation
- * for the remote Java Virtual Machine.
- *
- * @return byte[] - a byte array containing the current bytes
- * for the instrumentation exported by the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- byte[] getBytes() throws RemoteException;
-
- /**
- * Interface to get the size of the instrumentation buffer
- * for the target Java Virtual Machine.
- *
- * @return int - the size of the instrumentation buffer for the
- * remote Java Virtual Machine.
- * @throws RemoteException Thrown on any communication error
- */
- int getCapacity() throws RemoteException;
-
- /**
- * Interface to return the Local Virtual Machine Identifier for
- * the remote Java Virtual Machine. The Local Virtual Machine
- * Identifier is also know as the <em>lvmid</em>.
- *
- * @throws RemoteException Thrown on any communication error
- */
- int getLocalVmId() throws RemoteException;
-
- /**
- * Interface to detach from the remote Java Virtual Machine.
- *
- * @throws RemoteException Thrown on any communication error
- */
- void detach() throws RemoteException;
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor/remote/package.html Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- 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.
-
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides interfaces supporting remote monitoring for instrumented
-HotSpot Java Virtual Machines.
-</p>
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Wed Dec 02 09:34:55 2015 -0800
@@ -26,11 +26,8 @@
package sun.jvmstat.perfdata.monitor;
import java.util.List;
-import java.lang.reflect.*;
-import java.io.*;
import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
import sun.jvmstat.monitor.event.VmListener;
/**
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostProvider.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.util.*;
-import java.net.*;
-import java.io.*;
-import java.rmi.*;
-import java.util.HashMap;
-
-/**
- * Concrete implementation of the MonitoredHost interface for the
- * <em>rmi</em> protocol of the HotSpot PerfData monitoring implementation.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class MonitoredHostProvider extends MonitoredHost {
- private static final String serverName = "/JStatRemoteHost";
- private static final int DEFAULT_POLLING_INTERVAL = 1000;
-
- private ArrayList<HostListener> listeners;
- private NotifierTask task;
- private HashSet<Integer> activeVms;
- private RemoteVmManager vmManager;
- private RemoteHost remoteHost;
- private Timer timer;
-
- /**
- * Create a MonitoredHostProvider instance using the given HostIdentifier.
- *
- * @param hostId the host identifier for this MonitoredHost
- * @throws MonitorException Thrown on any error encountered while
- * communicating with the remote host.
- */
- public MonitoredHostProvider(HostIdentifier hostId)
- throws MonitorException {
- this.hostId = hostId;
- this.listeners = new ArrayList<HostListener>();
- this.interval = DEFAULT_POLLING_INTERVAL;
- this.activeVms = new HashSet<Integer>();
-
- String rmiName;
- String sn = serverName;
- String path = hostId.getPath();
-
- if ((path != null) && (path.length() > 0)) {
- sn = path;
- }
-
- if (hostId.getPort() != -1) {
- rmiName = "rmi://" + hostId.getHost() + ":" + hostId.getPort() + sn;
- } else {
- rmiName = "rmi://" + hostId.getHost() + sn;
- }
-
- try {
- remoteHost = (RemoteHost)Naming.lookup(rmiName);
-
- } catch (RemoteException e) {
- /*
- * rmi registry not available
- *
- * Access control exceptions, where the rmi server refuses a
- * connection based on policy file configuration, come through
- * here on the client side. Unfortunately, the RemoteException
- * doesn't contain enough information to determine the true cause
- * of the exception. So, we have to output a rather generic message.
- */
- String message = "RMI Registry not available at "
- + hostId.getHost();
-
- if (hostId.getPort() == -1) {
- message = message + ":"
- + java.rmi.registry.Registry.REGISTRY_PORT;
- } else {
- message = message + ":" + hostId.getPort();
- }
-
- if (e.getMessage() != null) {
- throw new MonitorException(message + "\n" + e.getMessage(), e);
- } else {
- throw new MonitorException(message, e);
- }
-
- } catch (NotBoundException e) {
- // no server with given name
- String message = e.getMessage();
- if (message == null) message = rmiName;
- throw new MonitorException("RMI Server " + message
- + " not available", e);
- } catch (MalformedURLException e) {
- // this is a programming problem
- e.printStackTrace();
- throw new IllegalArgumentException("Malformed URL: " + rmiName);
- }
- this.vmManager = new RemoteVmManager(remoteHost);
- this.timer = new Timer(true);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid)
- throws MonitorException {
- return getMonitoredVm(vmid, DEFAULT_POLLING_INTERVAL);
- }
-
- /**
- * {@inheritDoc}
- */
- public MonitoredVm getMonitoredVm(VmIdentifier vmid, int interval)
- throws MonitorException {
- VmIdentifier nvmid = null;
- try {
- nvmid = hostId.resolve(vmid);
- RemoteVm rvm = remoteHost.attachVm(vmid.getLocalVmId(),
- vmid.getMode());
- RemoteMonitoredVm rmvm = new RemoteMonitoredVm(rvm, nvmid, timer,
- interval);
- rmvm.attach();
- return rmvm;
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception attaching to "
- + nvmid.toString(), e);
- } catch (URISyntaxException e) {
- /*
- * the VmIdentifier is expected to be a valid and should resolve
- * easonably against the host identifier. A URISyntaxException
- * here is most likely a programming error.
- */
- throw new IllegalArgumentException("Malformed URI: "
- + vmid.toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach(MonitoredVm vm) throws MonitorException {
- RemoteMonitoredVm rmvm = (RemoteMonitoredVm)vm;
- rmvm.detach();
- try {
- remoteHost.detachVm(rmvm.getRemoteVm());
-
- } catch (RemoteException e) {
- throw new MonitorException("Remote Exception detaching from "
- + vm.getVmIdentifier().toString(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void addHostListener(HostListener listener) {
- synchronized(listeners) {
- listeners.add(listener);
- if (task == null) {
- task = new NotifierTask();
- timer.schedule(task, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeHostListener(HostListener listener) {
- /*
- * XXX: if a disconnect method is added, make sure it calls
- * this method to unregister this object from the watcher. otherwise,
- * an unused MonitoredHostProvider instance may go uncollected.
- */
- synchronized(listeners) {
- listeners.remove(listener);
- if (listeners.isEmpty() && (task != null)) {
- task.cancel();
- task = null;
- }
- }
- }
-
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (task != null) {
- task.cancel();
- NotifierTask oldTask = task;
- task = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldTask, task,
- oldInterval, newInterval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Set<Integer> activeVms() throws MonitorException {
- return vmManager.activeVms();
- }
-
- /**
- * Fire VmStatusChangeEvent events to HostListener objects
- *
- * @param active Set of Integer objects containing the local
- * Vm Identifiers of the active JVMs
- * @param started Set of Integer objects containing the local
- * Vm Identifiers of new JVMs started since last
- * interval.
- * @param terminated Set of Integer objects containing the local
- * Vm Identifiers of terminated JVMs since last
- * interval.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- private void fireVmStatusChangedEvents(Set<Integer> active, Set<Integer> started,
- Set<Integer> terminated) {
- ArrayList<HostListener> registered = null;
- VmStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new VmStatusChangeEvent(this, active, started, terminated);
- }
- l.vmStatusChanged(ev);
- }
- }
-
- /**
- * Fire hostDisconnectEvent events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireDisconnectedEvents() {
- ArrayList<HostListener> registered = null;
- HostEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<HostListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- HostListener l = i.next();
- if (ev == null) {
- ev = new HostEvent(this);
- }
- l.disconnected(ev);
- }
- }
-
- /**
- * class to poll the remote machine and generate local event notifications.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
-
- // save the last set of active JVMs
- Set<Integer> lastActiveVms = activeVms;
-
- try {
- // get the current set of active JVMs
- activeVms = (HashSet<Integer>)vmManager.activeVms();
-
- } catch (MonitorException e) {
- // XXX: use logging api
- System.err.println("MonitoredHostProvider: polling task "
- + "caught MonitorException:");
- e.printStackTrace();
-
- // mark the HostManager as errored and notify listeners
- setLastException(e);
- fireDisconnectedEvents();
- }
-
- if (activeVms.isEmpty()) {
- return;
- }
-
- Set<Integer> startedVms = new HashSet<>();
- Set<Integer> terminatedVms = new HashSet<>();
-
- for (Iterator<Integer> i = activeVms.iterator(); i.hasNext(); /* empty */ ) {
- Integer vmid = i.next();
- if (!lastActiveVms.contains(vmid)) {
- // a new file has been detected, add to set
- startedVms.add(vmid);
- }
- }
-
- for (Iterator<Integer> i = lastActiveVms.iterator(); i.hasNext();
- /* empty */ ) {
- Integer o = i.next();
- if (!activeVms.contains(o)) {
- // JVM has terminated, remove it from the active list
- terminatedVms.add(o);
- }
- }
-
- if (!startedVms.isEmpty() || !terminatedVms.isEmpty()) {
- fireVmStatusChangedEvents(activeVms, startedVms, terminatedVms);
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/MonitoredHostRmiService.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.MonitorException;
-import sun.jvmstat.monitor.MonitoredHost;
-import sun.jvmstat.monitor.MonitoredHostService;
-
-public final class MonitoredHostRmiService implements MonitoredHostService {
-
- @Override
- public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
- return new MonitoredHostProvider(hostId);
- }
-
- @Override
- public String getScheme() {
- return "rmi";
- }
-
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/PerfDataBuffer.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import java.nio.ByteBuffer;
-
-/**
- * The concrete PerfDataBuffer implementation for the <em>rmi:</em>
- * protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class is responsible for acquiring the instrumentation buffer
- * data for a remote target HotSpot Java Virtual Machine.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class PerfDataBuffer extends AbstractPerfDataBuffer {
-
- private RemoteVm rvm;
-
- /**
- * Create a PerfDataBuffer instance for accessing the specified
- * instrumentation buffer.
- *
- * @param rvm the proxy to the remote MonitredVm object
- * @param lvmid the local Java Virtual Machine Identifier of the
- * remote target.
- *
- * @throws MonitorException
- */
- public PerfDataBuffer(RemoteVm rvm, int lvmid) throws MonitorException {
-
- this.rvm = rvm;
- try {
- ByteBuffer buffer = ByteBuffer.allocate(rvm.getCapacity());
- sample(buffer);
- createPerfDataBuffer(buffer, lvmid);
-
- } catch (RemoteException e) {
- throw new MonitorException("Could not read data for remote JVM "
- + lvmid, e);
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * the local byte buffer.
- *
- * @param buffer the buffer to receive the copy of the remote
- * instrumentation buffer.
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample(ByteBuffer buffer) throws RemoteException {
- assert buffer != null;
- assert rvm != null;
- synchronized(buffer) {
- buffer.clear();
- buffer.put(rvm.getBytes());
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteMonitoredVm.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-import sun.jvmstat.perfdata.monitor.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.rmi.*;
-
-/**
- * Concrete implementation of the AbstractMonitoredVm class for the
- * <em>rmi:</em> protocol for the HotSpot PerfData monitoring implementation.
- * <p>
- * This class provides the ability to acquire to the instrumentation buffer
- * of a live, remote target Java Virtual Machine through an RMI server.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteMonitoredVm extends AbstractMonitoredVm {
-
- private ArrayList<VmListener> listeners;
- private NotifierTask notifierTask;
- private SamplerTask samplerTask;
- private Timer timer;
-
- private RemoteVm rvm;
- private ByteBuffer updateBuffer;
-
- /**
- * Create a RemoteMonitoredVm instance.
- *
- * @param rvm the proxy to the remote MonitoredVm instance.
- * @param vmid the vm identifier specifying the remot target JVM
- * @param timer the timer used to run polling tasks
- * @param interval the sampling interval
- */
- public RemoteMonitoredVm(RemoteVm rvm, VmIdentifier vmid,
- Timer timer, int interval)
- throws MonitorException {
- super(vmid, interval);
- this.rvm = rvm;
- pdb = new PerfDataBuffer(rvm, vmid.getLocalVmId());
- this.listeners = new ArrayList<VmListener>();
- this.timer = timer;
- }
-
- /**
- * Method to attach to the remote MonitoredVm.
- */
- public void attach() throws MonitorException {
- updateBuffer = pdb.getByteBuffer().duplicate();
-
- // if continuous sampling is requested, register with the sampler thread
- if (interval > 0) {
- samplerTask = new SamplerTask();
- timer.schedule(samplerTask, 0, interval);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach() {
- try {
- if (interval > 0) {
- if (samplerTask != null) {
- samplerTask.cancel();
- samplerTask = null;
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- notifierTask = null;
- }
- sample();
- }
- } catch (RemoteException e) {
- // XXX: - use logging api? throw an exception instead?
- System.err.println("Could not read data for remote JVM " + vmid);
- e.printStackTrace();
-
- } finally {
- super.detach();
- }
- }
-
- /**
- * Get a copy of the remote instrumentation buffer.
- *<p>
- * The data in the remote instrumentation buffer is copied into
- * a local byte buffer.
- *
- * @throws RemoteException Thrown on any communications errors with
- * the remote system.
- */
- public void sample() throws RemoteException {
- assert updateBuffer != null;
- ((PerfDataBuffer)pdb).sample(updateBuffer);
- }
-
- /**
- * Get the proxy to the remote MonitoredVm.
- *
- * @return RemoteVm - the proxy to the remote MonitoredVm.
- */
- public RemoteVm getRemoteVm() {
- return rvm;
- }
-
- /**
- * {@inheritDoc}
- */
- public void addVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.add(l);
- if (notifierTask == null) {
- notifierTask = new NotifierTask();
- timer.schedule(notifierTask, 0, interval);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeVmListener(VmListener l) {
- synchronized(listeners) {
- listeners.remove(l);
- if (listeners.isEmpty() && (notifierTask != null)) {
- notifierTask.cancel();
- notifierTask = null;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public void setInterval(int newInterval) {
- synchronized(listeners) {
- if (newInterval == interval) {
- return;
- }
-
- int oldInterval = interval;
- super.setInterval(newInterval);
-
- if (samplerTask != null) {
- samplerTask.cancel();
- SamplerTask oldSamplerTask = samplerTask;
- samplerTask = new SamplerTask();
- CountedTimerTaskUtils.reschedule(timer, oldSamplerTask,
- samplerTask, oldInterval,
- newInterval);
- }
- if (notifierTask != null) {
- notifierTask.cancel();
- NotifierTask oldNotifierTask = notifierTask;
- notifierTask = new NotifierTask();
- CountedTimerTaskUtils.reschedule(timer, oldNotifierTask,
- notifierTask, oldInterval,
- newInterval);
- }
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- *
- * @param inserted List of Monitor objects inserted.
- * @param removed List of Monitor objects removed.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorStatusChangedEvents(List<Monitor> inserted, List<Monitor> removed) {
- ArrayList<VmListener> registered = null;
- MonitorStatusChangeEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new MonitorStatusChangeEvent(this, inserted, removed);
- }
- l.monitorStatusChanged(ev);
- }
- }
-
- /**
- * Fire MonitoredVmStructureChanged events.
- */
- @SuppressWarnings("unchecked") // Cast of result of clone
- void fireMonitorsUpdatedEvents() {
- ArrayList<VmListener> registered = null;
- VmEvent ev = null;
-
- synchronized(listeners) {
- registered = (ArrayList)listeners.clone();
- }
-
- for (Iterator<VmListener> i = registered.iterator(); i.hasNext(); /* empty */) {
- VmListener l = i.next();
- if (ev == null) {
- ev = new VmEvent(this);
- }
- l.monitorsUpdated(ev);
- }
- }
-
- /*
- * Timer Tasks. There are two separate timer tasks here. The SamplerTask
- * is active whenever we are attached to the remote JVM with a periodic
- * sampling interval > 0. The NotifierTask is only active if a VmListener
- * has registered with this RemoteMonitoredVm instance. Also, in the future
- * we may want to run these tasks at different intervals. Currently,
- * they run at the same interval and some significant work may
- * need to be done to complete the separation of these two intervals.
- */
-
- /**
- * Class to periodically check the state of the defined monitors
- * for the remote MonitoredVm instance and to notify listeners of
- * any detected changes.
- */
- private class NotifierTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- MonitorStatus status = getMonitorStatus();
-
- List<Monitor> inserted = status.getInserted();
- List<Monitor> removed = status.getRemoved();
-
- if (!inserted.isEmpty() || !removed.isEmpty()) {
- fireMonitorStatusChangedEvents(inserted, removed);
- }
- } catch (MonitorException e) {
- // XXX: use logging api? fire disconnect events? mark errored?
- // fireDisconnectedEvents();
- System.err.println("Exception updating monitors for "
- + getVmIdentifier());
- e.printStackTrace();
- // XXX: should we cancle the notifierTask here?
- // this.cancel();
- }
- }
- }
-
- /**
- * Class to periodically sample the remote instrumentation byte buffer
- * and refresh the local copy. Registered listeners are notified of
- * the completion of a sampling event.
- */
- private class SamplerTask extends CountedTimerTask {
- public void run() {
- super.run();
- try {
- sample();
- fireMonitorsUpdatedEvents();
-
- } catch (RemoteException e) {
- // XXX: use logging api, mark vm as errored.
- System.err.println("Exception taking sample for "
- + getVmIdentifier());
- e.printStackTrace();
- this.cancel();
- }
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/RemoteVmManager.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.jvmstat.perfdata.monitor.protocol.rmi;
-
-import java.util.*;
-import java.util.regex.*;
-import java.io.*;
-import java.rmi.RemoteException;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Class for managing the RemoteMonitoredVm instances on a remote system.
- * <p>
- * This class is responsible for the mechanism that detects the active
- * HotSpot Java Virtual Machines on the remote host and possibly for a
- * specific user. The ability to detect all possible HotSpot Java Virtual
- * Machines on the remote host may be limited by the permissions of the
- * principal running the RMI server application on the remote host.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmManager {
-
- private RemoteHost remoteHost;
- private String user;
-
- /**
- * Creates a RemoteVmManager instance for the remote system.
- * <p>
- * Manages RemoteMonitordVm instances for which the principal
- * running the remote server has appropriate permissions.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- */
- public RemoteVmManager(RemoteHost remoteHost) {
- this(remoteHost, null);
- }
-
- /**
- * Creates a RemoteVmManager instance for the given user.
- * <p>
- * Manages RemoteMonitoredVm instances for all remote Java Virtual
- * machines owned by the specified user on the remote system. The
- * RMI server on the remote system must have the appropriate permissions
- * to access the named users Java Virtual Machines.
- *
- * @param remoteHost the remote proxy object to the RMI server on
- * the remote system.
- * @param user the name of the user
- */
- public RemoteVmManager(RemoteHost remoteHost, String user) {
- this.user = user;
- this.remoteHost = remoteHost;
- }
-
- /**
- * Return the current set of monitorable Java Virtual Machines.
- * <p>
- * The set returned by this method depends on the user name passed
- * to the constructor. If no user name was specified, then this
- * method will return all candidate JVMs on the system. Otherwise,
- * only the JVMs for the given user will be returned. This assumes
- * that the RMI server process has the appropriate permissions to
- * access the target set of JVMs.
- *
- * @return Set - the Set of monitorable Java Virtual Machines
- */
- public Set<Integer> activeVms() throws MonitorException {
- int[] active = null;
-
- try {
- active = remoteHost.activeVms();
-
- } catch (RemoteException e) {
- throw new MonitorException("Error communicating with remote host: "
- + e.getMessage(), e);
- }
-
- Set<Integer> activeSet = new HashSet<Integer>(active.length);
-
- for (int i = 0; i < active.length; i++) {
- activeSet.add(active[i]);
- }
-
- return activeSet;
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/rmi/package.html Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<!doctype html public "-//IETF//DTD HTML/EN">
-<html>
-<head>
-<!--
-
-
- Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- 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.
-
--->
-</head>
-<body bgcolor="white">
-<p>
-Provides the implementation classes for the <em>rmi:</em> protocol for
-the HotSpot PerfData instrumentation buffer monitoring implementation.
-</p>
-<p>
-The <em>rmi:</em> protocol is the default protocol for the PerfData
-implementation when a hostname is specified as part of a HostIdentifier
-or VMIdentifier. It communicates with an RMI server on the remote machine
-that provides functions to get a list of available Java Virtual Machines
-and to acquire a copy of a Java Virtual Machine's instrumentation buffer.
-The RMI server may or may not use the PerfData implementation on the
-remote host to acquire this information. The <em>jstatd</em> server
-provides a PerfData implementation of the RMI server.
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2004, 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 sun.tools.jstatd;
-
-import java.rmi.*;
-import java.rmi.server.*;
-import java.rmi.registry.Registry;
-import java.rmi.registry.LocateRegistry;
-import java.net.MalformedURLException;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Application providing remote access to the jvmstat instrumentation
- * exported by local Java Virtual Machine processes. Remote access is
- * provided through an RMI interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class Jstatd {
-
- private static Registry registry;
- private static int port = -1;
- private static boolean startRegistry = true;
-
- private static void printUsage() {
- System.err.println("usage: jstatd [-nr] [-p port] [-n rminame]");
- }
-
- static void bind(String name, RemoteHostImpl remoteHost)
- throws RemoteException, MalformedURLException, Exception {
-
- try {
- Naming.rebind(name, remoteHost);
- } catch (java.rmi.ConnectException e) {
- /*
- * either the registry is not running or we cannot contact it.
- * start an internal registry if requested.
- */
- if (startRegistry && registry == null) {
- int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
- registry = LocateRegistry.createRegistry(localport);
- bind(name, remoteHost);
- } else {
- throw e;
- }
- }
- }
-
- @SuppressWarnings("deprecation") // Use of RMISecurityManager
- public static void main(String[] args) {
- String rminame = null;
- int argc = 0;
-
- for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
- String arg = args[argc];
-
- if (arg.compareTo("-nr") == 0) {
- startRegistry = false;
- } else if (arg.startsWith("-p")) {
- if (arg.compareTo("-p") != 0) {
- port = Integer.parseInt(arg.substring(2));
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- port = Integer.parseInt(args[argc]);
- }
- } else if (arg.startsWith("-n")) {
- if (arg.compareTo("-n") != 0) {
- rminame = arg.substring(2);
- } else {
- argc++;
- if (argc >= args.length) {
- printUsage();
- System.exit(1);
- }
- rminame = args[argc];
- }
- } else {
- printUsage();
- System.exit(1);
- }
- }
-
- if (argc < args.length) {
- printUsage();
- System.exit(1);
- }
-
- if (System.getSecurityManager() == null) {
- System.setSecurityManager(new RMISecurityManager());
- }
-
- StringBuilder name = new StringBuilder();
-
- if (port >= 0) {
- name.append("//:").append(port);
- }
-
- if (rminame == null) {
- rminame = "JStatRemoteHost";
- }
-
- name.append("/").append(rminame);
-
- try {
- // use 1.5.0 dynamically generated subs.
- System.setProperty("java.rmi.server.ignoreSubClasses", "true");
- RemoteHostImpl remoteHost = new RemoteHostImpl();
- RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
- remoteHost, 0);
- bind(name.toString(), remoteHost);
- System.out.println("jstatd started (bound to " + name.toString() + ")");
- System.out.flush();
- } catch (MalformedURLException e) {
- if (rminame != null) {
- System.out.println("Bad RMI server name: " + rminame);
- } else {
- System.out.println("Bad RMI URL: " + name);
- }
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (java.rmi.ConnectException e) {
- // could not attach to or create a registry
- System.out.println("Could not contact RMI registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (RemoteException e) {
- System.out.println("Could not bind " + name + " to RMI Registry");
- e.printStackTrace(System.out);
- System.exit(1);
- } catch (Exception e) {
- System.out.println("Could not create remote object");
- e.printStackTrace(System.out);
- System.exit(1);
- }
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteHostImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import java.util.*;
-import java.nio.*;
-import java.io.*;
-import java.net.*;
-import java.rmi.*;
-import java.rmi.server.*;
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.event.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteHost interface for the HotSpot
- * PerfData <em>rmi:</em> protocol.
- * <p>
- * This class provides remote access to the instrumentation exported
- * by HotSpot Java Virtual Machines through the PerfData shared memory
- * interface.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteHostImpl implements RemoteHost, HostListener {
-
- private MonitoredHost monitoredHost;
- private Set<Integer> activeVms;
-
- public RemoteHostImpl() throws MonitorException {
- try {
- monitoredHost = MonitoredHost.getMonitoredHost("localhost");
- } catch (URISyntaxException e) { }
-
- activeVms = monitoredHost.activeVms();
- monitoredHost.addHostListener(this);
- }
-
- public RemoteVm attachVm(int lvmid, String mode)
- throws RemoteException, MonitorException {
- Integer v = lvmid;
- RemoteVm stub = null;
- StringBuilder sb = new StringBuilder();
-
- sb.append("local://").append(lvmid).append("@localhost");
- if (mode != null) {
- sb.append("?mode=").append(mode);
- }
-
- String vmidStr = sb.toString();
-
- try {
- VmIdentifier vmid = new VmIdentifier(vmidStr);
- MonitoredVm mvm = monitoredHost.getMonitoredVm(vmid);
- RemoteVmImpl rvm = new RemoteVmImpl((BufferedMonitoredVm)mvm);
- stub = (RemoteVm) UnicastRemoteObject.exportObject(rvm, 0);
- }
- catch (URISyntaxException e) {
- throw new RuntimeException("Malformed VmIdentifier URI: "
- + vmidStr, e);
- }
- return stub;
- }
-
- public void detachVm(RemoteVm rvm) throws RemoteException {
- rvm.detach();
- }
-
- public int[] activeVms() throws MonitorException {
- Object[] vms = null;
- int[] vmids = null;
-
- vms = monitoredHost.activeVms().toArray();
- vmids = new int[vms.length];
-
- for (int i = 0; i < vmids.length; i++) {
- vmids[i] = ((Integer)vms[i]).intValue();
- }
- return vmids;
- }
-
- public void vmStatusChanged(VmStatusChangeEvent ev) {
- synchronized(this.activeVms) {
- activeVms.retainAll(ev.getActive());
- }
- }
-
- public void disconnected(HostEvent ev) {
- // we only monitor the local host, so this event shouldn't occur.
- }
-}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/RemoteVmImpl.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.tools.jstatd;
-
-import sun.jvmstat.monitor.*;
-import sun.jvmstat.monitor.remote.*;
-
-/**
- * Concrete implementation of the RemoteVm interface for the HotSpot PerfData
- * shared memory implementation of the jvmstat monitoring APIs. This class
- * providing remote access to the instrumentation exported by a local HotSpot
- * Java Virtual Machine. The instrumentation buffer is shipped in whole to
- * the remote machine, which is responsible for parsing and provide access
- * to the contained data.
- *
- * @author Brian Doherty
- * @since 1.5
- */
-public class RemoteVmImpl implements RemoteVm {
-
- private BufferedMonitoredVm mvm;
-
- RemoteVmImpl(BufferedMonitoredVm mvm) {
- this.mvm = mvm;
- }
-
- public byte[] getBytes() {
- return mvm.getBytes();
- }
-
- public int getCapacity() {
- return mvm.getCapacity();
- }
-
- public void detach() {
- mvm.detach();
- }
-
- public int getLocalVmId() {
- return mvm.getVmIdentifier().getLocalVmId();
- }
-}
--- a/jdk/test/TEST.groups Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/TEST.groups Wed Dec 02 09:34:55 2015 -0800
@@ -173,6 +173,7 @@
com/sun/security \
-com/sun/security/jgss \
com/sun/org/apache/xml/internal/security \
+ jdk/security \
sun/security \
-sun/security/krb5 \
-sun/security/jgss \
@@ -453,6 +454,7 @@
:jdk_jdi \
com/sun/tools \
demo \
+ jdk/security/jarsigner \
sun/security/tools/jarsigner \
sun/security/tools/policytool \
sun/rmi/rmic \
--- a/jdk/test/com/sun/jdi/DoubleAgentTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/com/sun/jdi/DoubleAgentTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,7 +31,7 @@
*
* @library /lib/testlibrary
* @modules java.management
- * @build jdk.testlibarary.*
+ * @build jdk.testlibrary.*
* @build DoubleAgentTest Exit0
* @run driver DoubleAgentTest
*/
--- a/jdk/test/com/sun/jdi/SuspendNoFlagTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/com/sun/jdi/SuspendNoFlagTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -29,7 +29,7 @@
* @summary Test for JDWP: -agentlib:jdwp=suspend=n hanging
* @library /lib/testlibrary
* @modules java.management
- * @build jdk.testlibarary.*
+ * @build jdk.testlibrary.*
* @compile -g HelloWorld.java
* @run driver SuspendNoFlagTest
*/
--- a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.java Wed Dec 02 09:34:55 2015 -0800
@@ -41,9 +41,9 @@
* @library /test/lib/share/classes
* @build jdk.testlibrary.*
* @build jdk.test.lib.hprof.*
- * @build jdk.test.lib.hprof.module.*
+ * @build jdk.test.lib.hprof.model.*
* @build jdk.test.lib.hprof.parser.*
- * @build jdk.test.lib.hprof.utils.*
+ * @build jdk.test.lib.hprof.util.*
* @run main DumpHeap
*/
public class DumpHeap {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/ToString.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136500
+ * @summary Test Integer.toString method
+ */
+
+public class ToString {
+
+ public static void main(String[] args) throws Exception {
+ test("-2147483648", Integer.MIN_VALUE);
+ test("2147483647", Integer.MAX_VALUE);
+ test("0", 0);
+
+ // Wiggle around the exponentially increasing base.
+ final int LIMIT = (1 << 15);
+ int base = 10000;
+ while (base < Integer.MAX_VALUE / 10) {
+ for (int d = -LIMIT; d < LIMIT; d++) {
+ int c = base + d;
+ if (c > 0) {
+ buildAndTest(c);
+ }
+ }
+ base *= 10;
+ }
+
+ for (int c = 1; c < LIMIT; c++) {
+ buildAndTest(Integer.MAX_VALUE - LIMIT + c);
+ }
+ }
+
+ private static void buildAndTest(int c) {
+ if (c <= 0) {
+ throw new IllegalArgumentException("Test bug: can only handle positives, " + c);
+ }
+
+ StringBuilder sbN = new StringBuilder();
+ StringBuilder sbP = new StringBuilder();
+
+ int t = c;
+ while (t > 0) {
+ char digit = (char) ('0' + (t % 10));
+ sbN.append(digit);
+ sbP.append(digit);
+ t = t / 10;
+ }
+
+ sbN.append("-");
+ sbN.reverse();
+ sbP.reverse();
+
+ test(sbN.toString(), -c);
+ test(sbP.toString(), c);
+ }
+
+ private static void test(String expected, int value) {
+ String actual = Integer.toString(value);
+ if (!expected.equals(actual)) {
+ throw new RuntimeException("Expected " + expected + ", but got " + actual);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Long/ToString.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136500
+ * @summary Test Long.toString method
+ */
+
+public class ToString {
+
+ public static void main(String[] args) throws Exception {
+ test("-9223372036854775808", Long.MIN_VALUE);
+ test("9223372036854775807", Long.MAX_VALUE);
+ test("0", 0);
+
+ // Wiggle around the exponentially increasing base.
+ final int LIMIT = (1 << 15);
+ long base = 10000;
+ while (base < Long.MAX_VALUE / 10) {
+ for (int d = -LIMIT; d < LIMIT; d++) {
+ long c = base + d;
+ if (c > 0) {
+ buildAndTest(c);
+ }
+ }
+ base *= 10;
+ }
+
+ for (int c = 1; c < LIMIT; c++) {
+ buildAndTest(Long.MAX_VALUE - LIMIT + c);
+ }
+ }
+
+ private static void buildAndTest(long c) {
+ if (c <= 0) {
+ throw new IllegalArgumentException("Test bug: can only handle positives, " + c);
+ }
+
+ StringBuilder sbN = new StringBuilder();
+ StringBuilder sbP = new StringBuilder();
+
+ long t = c;
+ while (t > 0) {
+ char digit = (char) ('0' + (t % 10));
+ sbN.append(digit);
+ sbP.append(digit);
+ t = t / 10;
+ }
+
+ sbN.append("-");
+ sbN.reverse();
+ sbP.reverse();
+
+ test(sbN.toString(), -c);
+ test(sbP.toString(), c);
+ }
+
+ private static void test(String expected, long value) {
+ String actual = Long.toString(value);
+ if (!expected.equals(actual)) {
+ throw new RuntimeException("Expected " + expected + ", but got " + actual);
+ }
+ }
+}
--- a/jdk/test/java/lang/ProcessHandle/TreeTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/lang/ProcessHandle/TreeTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -29,6 +29,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
@@ -168,8 +169,16 @@
// Wait for direct children to be created and save the list
List<ProcessHandle> subprocesses = waitForAllChildren(p1Handle, spawnNew);
+ Optional<Instant> p1Start = p1Handle.info().startInstant();
for (ProcessHandle ph : subprocesses) {
Assert.assertTrue(ph.isAlive(), "Child should be alive: " + ph);
+ // Verify each child was started after the parent
+ ph.info().startInstant()
+ .ifPresent(childStart -> p1Start.ifPresent(parentStart -> {
+ Assert.assertFalse(childStart.isBefore(parentStart),
+ String.format("Child process started before parent: child: %s, parent: %s",
+ childStart, parentStart));
+ }));
}
// Each child spawns two processes and waits for commands
@@ -178,7 +187,7 @@
// Poll until all 9 child processes exist or the timeout is reached
int expected = 9;
- long timeout = Utils.adjustTimeout(10L);
+ long timeout = Utils.adjustTimeout(60L);
Instant endTimeout = Instant.now().plusSeconds(timeout);
do {
Thread.sleep(200L);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/AcrossThreads.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8143214
+ * @summary Verify that StackWalker works well when one instance of StackWalker
+ * is used by several threads sequentially or concurrently.
+ * @run testng AcrossThreads
+ */
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.lang.StackWalker.StackFrame;
+import static java.lang.StackWalker.Option.*;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class AcrossThreads {
+ static final StackWalker WALKERS[] = new StackWalker[] {
+ StackWalker.getInstance(RETAIN_CLASS_REFERENCE),
+ StackWalker.getInstance(EnumSet.of(SHOW_REFLECT_FRAMES, RETAIN_CLASS_REFERENCE)),
+ StackWalker.getInstance(EnumSet.of(SHOW_HIDDEN_FRAMES, RETAIN_CLASS_REFERENCE))
+ };
+
+ @DataProvider
+ public StackWalker[][] walkerProvider() {
+ return new StackWalker[][] {
+ new StackWalker[] { WALKERS[0] },
+ new StackWalker[] { WALKERS[1] },
+ new StackWalker[] { WALKERS[2] }
+ };
+ }
+
+ @Test(dataProvider = "walkerProvider")
+ public void test(StackWalker walker) {
+ Thread t1 = new T1(walker);
+ // call methods of one instance of StackWalker sequentially in T1, T2, T3.
+ t1.start();
+ try {
+ t1.join();
+ } catch (InterruptedException e) { }
+
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < 100; i++) {
+ threads.add(new T1(walker));
+ threads.add(new T2(walker));
+ threads.add(new T3(walker));
+ }
+ // call methods of one instance of StackWalker concurrently in several threads.
+ threads.parallelStream().forEach(t -> {
+ t.setDaemon(true);
+ t.start();
+ });
+ threads.parallelStream().forEach(t -> {
+ try {
+ t.join();
+ } catch (InterruptedException e) { }
+ });
+ }
+
+ interface Consumer {
+ final int LOOPS = 5;
+
+ public void consume();
+
+ default public void assertWalker(StackWalker walker, int n) {
+ if (--n == 0) {
+ Map<String, Integer> methods = new HashMap<String, Integer>();
+ walker.forEach(f -> {
+ Integer i = methods.putIfAbsent(f.getMethodName(), 1);
+ if (i != null) {
+ methods.put(f.getMethodName(), i + 1);
+ }
+ });
+
+ // verify that walker.forEach(...) reaches the specified methods.
+ assertTrue(methods.get("consume") == 1);
+ assertTrue(methods.get("run") == 1);
+ assertTrue(methods.get("assertWalker") == LOOPS);
+
+ // verify that walker.walk(...) reaches the specified methods.
+ assertTrue(walker.walk(s -> s.map(StackFrame::getMethodName)
+ .filter(mn -> mn.equals("consume"))
+ .count()) == 1);
+ assertTrue(walker.walk(s -> s.map(StackFrame::getMethodName)
+ .filter(mn -> mn.equals("run"))
+ .count()) == 1);
+ assertTrue(walker.walk(s -> s.map(StackFrame::getMethodName)
+ .filter(mn -> mn.equals("assertWalker"))
+ .count()) == LOOPS);
+ } else {
+ assertWalker(walker, n);
+ }
+ }
+ }
+
+ class T1 extends Thread implements Consumer {
+ final StackWalker walker;
+
+ public T1(StackWalker walker) {
+ this.walker = walker;
+ }
+
+ public void run() {
+ consume();
+
+ Thread t2 = new T2(walker);
+ t2.start();
+ try {
+ t2.join();
+ } catch (InterruptedException e) { }
+
+ consume();
+ }
+
+ public void consume() {
+ assertWalker(walker, LOOPS);
+
+ // verify walker.walk() reaches T1 class through methods run() and consume().
+ assertTrue(walker.walk(s -> s.filter(f -> T1.class == f.getDeclaringClass())
+ .count()) == 2);
+
+ assertCallerClass(walker);
+ assertEquals(T1.class, walker.getCallerClass());
+ }
+ }
+
+ class T2 extends Thread implements Consumer {
+ final StackWalker walker;
+
+ public T2(StackWalker walker) {
+ this.walker = walker;
+ }
+
+ public void run() {
+ consume();
+
+ Thread t3 = new T3(walker);
+ t3.start();
+ try {
+ t3.join();
+ } catch (InterruptedException e) { }
+
+ consume();
+ }
+
+ public void consume() {
+ assertWalker(walker, LOOPS);
+
+ // verify walker.walk() reaches T2 class through methods run() and consume().
+ assertTrue(walker.walk(s -> s.filter(f -> T2.class == f.getDeclaringClass())
+ .count()) == 2);
+ // verify T1 is not reached, even if call is invoked
+ // from test()->T1.start()->T1.run()->T2
+ assertTrue(walker.walk(s -> s.filter(f -> T1.class == f.getDeclaringClass())
+ .count()) == 0);
+
+ assertCallerClass(walker);
+ assertEquals(T2.class, walker.getCallerClass());
+ }
+ }
+
+ class T3 extends Thread implements Consumer {
+ final StackWalker walker;
+
+ public T3(StackWalker walker) {
+ this.walker = walker;
+ }
+
+ public void run() {
+ consume();
+ }
+
+ public void consume() {
+ assertWalker(walker, LOOPS);
+
+ // verify walker.walk() reaches T1 class through methods run() and consume().
+ assertTrue(walker.walk(s -> s.filter(f -> T3.class == f.getDeclaringClass())
+ .count()) == 2);
+ // verify T1, T2 is not reached, even if call is invoked
+ // from test() -> T1.start() -> T1.run() -> T2.start() -> T2.run() -> T3
+ assertTrue(walker.walk(s -> s.filter(f -> T2.class == f.getDeclaringClass())
+ .count()) == 0);
+ assertTrue(walker.walk(s -> s.filter(f -> T1.class == f.getDeclaringClass())
+ .count()) == 0);
+
+ assertCallerClass(walker);
+ assertEquals(T3.class, walker.getCallerClass());
+ }
+ }
+
+ static void assertCallerClass(StackWalker walker) {
+ // verify walker.getCallerClass() get the expected class.
+ call(walker);
+ }
+
+ static void call(StackWalker walker) {
+ Class<?> c = walker.getCallerClass();
+ assertEquals(c, AcrossThreads.class);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8140450
+ * @summary Basic test for the StackWalker::walk method
+ * @run testng Basic
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.util.List;
+import java.util.stream.Collectors;
+import static java.lang.StackWalker.Option.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class Basic {
+ private static boolean verbose = false;
+
+ @DataProvider(name = "stackDepths")
+ public static Object[][] stackDepths() {
+ return new Object[][] {
+ { new int[] { 12 }, new int[] { 4, 8, 12} },
+ { new int[] { 18 }, new int[] { 8, 16, 20} },
+ { new int[] { 32 }, new int[] { 16, 32, 64} },
+ };
+ }
+
+ /**
+ * For a stack of a given depth, it creates a StackWalker with an estimate.
+ * Test walking different number of frames
+ */
+ @Test(dataProvider = "stackDepths")
+ public static void test(int[] depth, int[] estimates) {
+ Basic test = new Basic(depth[0]);
+ for (int estimate : estimates) {
+ test.walk(estimate);
+ }
+ }
+
+ private final int depth;
+ Basic(int depth) {
+ this.depth = depth;
+ }
+
+ /*
+ * Setup a stack builder with the expected stack depth
+ * Walk the stack and count the frames.
+ */
+ void walk(int estimate) {
+ int limit = Math.min(depth, 16);
+ List<StackFrame> frames = new StackBuilder(depth, limit).build();
+ System.out.format("depth=%d estimate=%d expected=%d walked=%d%n",
+ depth, estimate, limit, frames.size());
+ assertEquals(limit, frames.size());
+ }
+
+ class StackBuilder {
+ private final int stackDepth;
+ private final int limit;
+ private int depth = 0;
+ private List<StackFrame> result;
+ StackBuilder(int stackDepth, int limit) {
+ this.stackDepth = stackDepth; // build method;
+ this.limit = limit;
+ }
+ List<StackFrame> build() {
+ trace("build");
+ m1();
+ return result;
+ }
+ void m1() {
+ trace("m1");
+ m2();
+ }
+ void m2() {
+ trace("m2");
+ m3();
+ }
+ void m3() {
+ trace("m3");
+ m4();
+ }
+ void m4() {
+ trace("m4");
+ int remaining = stackDepth-depth-1;
+ if (remaining >= 4) {
+ m1();
+ } else {
+ filler(remaining);
+ }
+ }
+ void filler(int i) {
+ trace("filler");
+ if (i == 0)
+ walk();
+ else
+ filler(--i);
+ }
+
+ void walk() {
+ StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
+ result = walker.walk(s -> s.limit(limit).collect(Collectors.toList()));
+ }
+ void trace(String methodname) {
+ ++depth;
+ if (verbose)
+ System.out.format("%2d: %s%n", depth, methodname);
+ }
+ }
+
+ static void assertEquals(int x, int y) {
+ if (x != y) {
+ throw new RuntimeException(x + " != " + y);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/CallerFromMain.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8140450
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @summary Test if the getCallerClass method returns empty optional
+ * @run main CallerFromMain exec
+ */
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.OutputAnalyzer;
+
+public class CallerFromMain {
+
+ private static final StackWalker sw = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ public static void main(String[] args) throws Exception {
+ if (args.length > 0) {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "CallerFromMain");
+ OutputAnalyzer output = ProcessTools.executeProcess(pb);
+ System.out.println(output.getOutput());
+ output.shouldHaveExitValue(0);
+ return;
+ }
+
+ // StackWalker::getCallerClass
+ // CallerFromMain::main
+ // no caller
+ try {
+ Class<?> c = sw.getCallerClass();
+ throw new RuntimeException("UOE not thrown. Caller: " + c);
+ } catch (IllegalStateException e) {}
+
+ // StackWalker::getCallerClass
+ // Runnable::run
+ // Thread::run
+ Thread t1 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Class<?> c = sw.getCallerClass();
+ System.out.println("Call from Thread.run: " + c);
+ assertThreadClassAsCaller(c);
+ }
+ });
+ t1.setDaemon(true);
+ t1.start();
+
+ // StackWalker::getCallerClass
+ // CallerFromMain::doit
+ // Thread::run
+ Thread t2 = new Thread(CallerFromMain::doit);
+ t2.setDaemon(true);
+ t2.start();
+
+ // StackWalker::getCallerClass
+ // MyRunnable::run
+ // Thread::run
+ Thread t3 = new Thread(new MyRunnable());
+ t3.setDaemon(true);
+ t3.start();
+
+ // StackWalker::getCallerClass
+ // Runnable::run
+ // MyThread::run
+ Thread t4 = new MyThread(new Runnable() {
+ @Override
+ public void run() {
+ Class<?> c = sw.getCallerClass();
+ System.out.println("Call from MyThread.run: " + c);
+ if (c != MyThread.class) {
+ throw new RuntimeException("Expected MyThread.class but got " + c);
+ }
+ }
+ });
+ t4.setDaemon(true);
+ t4.start();
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+ }
+
+ static class MyThread extends Thread {
+ final Runnable runnable;
+ MyThread(Runnable runnable) {
+ super("MyThread");
+ this.runnable = runnable;
+ }
+ public void run() {
+ runnable.run();
+ }
+ }
+
+ static class MyRunnable implements Runnable {
+ @Override
+ public void run() {
+ Class<?> c = sw.getCallerClass();
+ System.out.println("Call from Thread::run: " + c);
+ assertThreadClassAsCaller(c);
+ }
+ }
+
+ static void doit() {
+ Class<?> c = sw.getCallerClass();
+ System.out.println("Call from CallerFromMain.doit: " + c);
+ assertThreadClassAsCaller(c);
+ }
+
+ static void assertThreadClassAsCaller(Class<?> caller) {
+ if (caller != Thread.class) {
+ throw new RuntimeException("Expected Thread.class but got " + caller);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/DumpStackTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8143214
+ * @summary Verify outputs of Thread.dumpStack() and Throwable.printStackTrace().
+ * This test should also been run against jdk9 successfully except of
+ * VM option MemberNameInStackFrame.
+ * @run main/othervm DumpStackTest
+ * @run main/othervm -Dstackwalk.newThrowable=false DumpStackTest
+ * @run main/othervm -Dstackwalk.newThrowable=true -XX:-MemberNameInStackFrame DumpStackTest
+ * @run main/othervm -Dstackwalk.newThrowable=true -XX:+MemberNameInStackFrame DumpStackTest
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+public class DumpStackTest {
+
+ public static void main(String args[]) {
+ test();
+ testThread();
+ testLambda();
+ testMethodInvoke();
+ testMethodHandle();
+ }
+
+ static class CallFrame {
+ final String classname;
+ final String methodname;
+ CallFrame(Class<?> c, String methodname) {
+ this(c.getName(), methodname);
+ }
+ CallFrame(String classname, String methodname) {
+ this.classname = classname;
+ this.methodname = methodname;
+ }
+
+ String getClassName() {
+ return classname;
+ }
+ String getMethodName() {
+ return methodname;
+ }
+ String getFileName() {
+ int i = classname.lastIndexOf('.');
+ int j = classname.lastIndexOf('$');
+ String name = classname.substring(i+1, j >= 0 ? j : classname.length());
+ return name + ".java";
+ }
+ @Override
+ public String toString() {
+ return classname + "." + methodname + "(" + getFileName() + ")";
+ }
+ }
+
+ static void test() {
+ CallFrame[] callStack = new CallFrame[] {
+ new CallFrame(Thread.class, "getStackTrace"),
+ new CallFrame(DumpStackTest.class, "test"),
+ new CallFrame(DumpStackTest.class, "main"),
+ // if invoked from jtreg
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke0"), // non-public class
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke"),
+ new CallFrame("sun.reflect.DelegatingMethodAccessorImpl", "invoke"),
+ new CallFrame(Method.class, "invoke"),
+ new CallFrame(Thread.class, "run"),
+ };
+
+ assertStackTrace(Thread.currentThread().getStackTrace(), callStack);
+ getStackTrace(callStack);
+ }
+
+ static void getStackTrace(CallFrame[] callStack) {
+ // this method is the top of the stack
+ callStack[0] = new CallFrame(DumpStackTest.class, "getStackTrace");
+
+ try {
+ throw new RuntimeException();
+ } catch(RuntimeException ex) {
+ assertStackTrace(ex.getStackTrace(), callStack);
+ }
+ }
+ static void testThread() {
+ Thread t1 = new Thread() {
+ public void run() {
+ c();
+ }
+
+ void c() {
+ CallFrame[] callStack = new CallFrame[] {
+ new CallFrame(Thread.class, "getStackTrace"),
+ new CallFrame(this.getClass(), "c"),
+ new CallFrame(this.getClass(), "run")
+ };
+ assertStackTrace(Thread.currentThread().getStackTrace(), callStack);
+ DumpStackTest.getStackTrace(callStack);
+ }
+ };
+ t1.start();
+ try {
+ t1.join();
+ } catch(InterruptedException e) {}
+ }
+
+ static void testLambda() {
+ Consumer<Void> c = (x) -> consumeLambda();
+ c.accept(null);
+ }
+
+ static void consumeLambda() {
+ CallFrame[] callStack = new CallFrame[]{
+ new CallFrame(Thread.class, "getStackTrace"),
+ new CallFrame(DumpStackTest.class, "consumeLambda"),
+ new CallFrame(DumpStackTest.class, "lambda$testLambda$0"),
+ new CallFrame(DumpStackTest.class, "testLambda"),
+ new CallFrame(DumpStackTest.class, "main"),
+ // if invoked from jtreg
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke0"),
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke"),
+ new CallFrame("sun.reflect.DelegatingMethodAccessorImpl", "invoke"),
+ new CallFrame(Method.class, "invoke"),
+ new CallFrame(Thread.class, "run")
+ };
+ assertStackTrace(Thread.currentThread().getStackTrace(), callStack);
+ DumpStackTest.getStackTrace(callStack);
+ }
+
+ static void testMethodInvoke() {
+ try {
+ Method m = DumpStackTest.class.getDeclaredMethod("methodInvoke");
+ m.invoke(null);
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void methodInvoke() {
+ CallFrame[] callStack = new CallFrame[] {
+ new CallFrame(Thread.class, "getStackTrace"),
+ new CallFrame(DumpStackTest.class, "methodInvoke"),
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke0"),
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke"),
+ new CallFrame("sun.reflect.DelegatingMethodAccessorImpl", "invoke"),
+ new CallFrame(Method.class, "invoke"),
+ new CallFrame(DumpStackTest.class, "testMethodInvoke"),
+ new CallFrame(DumpStackTest.class, "main"),
+ // if invoked from jtreg
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke0"),
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke"),
+ new CallFrame("sun.reflect.DelegatingMethodAccessorImpl", "invoke"),
+ new CallFrame(Method.class, "invoke"),
+ new CallFrame(Thread.class, "run")
+ };
+ assertStackTrace(Thread.currentThread().getStackTrace(), callStack);
+ DumpStackTest.getStackTrace(callStack);
+ }
+
+ static void testMethodHandle() {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ MethodHandle handle = lookup.findStatic(DumpStackTest.class, "methodHandle",
+ MethodType.methodType(void.class));
+ handle.invoke();
+ } catch(Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ static void methodHandle() {
+ CallFrame[] callStack = new CallFrame[]{
+ new CallFrame(Thread.class, "getStackTrace"),
+ new CallFrame(DumpStackTest.class, "methodHandle"),
+ new CallFrame(DumpStackTest.class, "testMethodHandle"),
+ new CallFrame(DumpStackTest.class, "main"),
+ // if invoked from jtreg
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke0"),
+ new CallFrame("sun.reflect.NativeMethodAccessorImpl", "invoke"),
+ new CallFrame("sun.reflect.DelegatingMethodAccessorImpl", "invoke"),
+ new CallFrame(Method.class, "invoke"),
+ new CallFrame(Thread.class, "run")
+ };
+ assertStackTrace(Thread.currentThread().getStackTrace(), callStack);
+ DumpStackTest.getStackTrace(callStack);
+ }
+
+ static void assertStackTrace(StackTraceElement[] actual, CallFrame[] expected) {
+ System.out.println("--- Actual ---");
+ Arrays.stream(actual).forEach(e -> System.out.println(e));
+ System.out.println("--- Expected ---");
+ Arrays.stream(expected).forEach(e -> System.out.println(e));
+
+ for (int i = 0, j = 0; i < actual.length; i++) {
+ // filter test framework classes
+ if (actual[i].getClassName().startsWith("com.sun.javatest.regtest"))
+ continue;
+ assertEquals(actual[i], expected[j++], i);
+ }
+
+ }
+ static void assertEquals(StackTraceElement actual, CallFrame expected, int idx) {
+ if (!actual.getClassName().equals(expected.getClassName()) ||
+ !actual.getFileName().equals(expected.getFileName()) ||
+ !actual.getMethodName().equals(expected.getMethodName())) {
+ throw new RuntimeException("StackTraceElements mismatch at index " + idx +
+ ". Expected [" + expected + "], but get [" + actual + "]");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/EmbeddedStackWalkTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @bug 8143214
+ * @summary Verify StackWalker works well when embedded in another
+ * StackWalker's functions.
+ * @run testng/othervm EmbeddedStackWalkTest
+ */
+
+import java.lang.StackWalker.StackFrame;
+import static java.lang.StackWalker.Option.*;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Arrays;
+import java.util.EnumSet;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class EmbeddedStackWalkTest {
+ static final StackWalker WALKERS[] = new StackWalker[] {
+ StackWalker.getInstance(RETAIN_CLASS_REFERENCE),
+ StackWalker.getInstance(EnumSet.of(SHOW_REFLECT_FRAMES, RETAIN_CLASS_REFERENCE)),
+ StackWalker.getInstance(EnumSet.of(SHOW_HIDDEN_FRAMES, RETAIN_CLASS_REFERENCE))
+ };
+
+ static final int BIG_LOOP = 30;
+ static final int SMALL_LOOP = 5;
+
+ @DataProvider
+ public StackWalker[][] walkerProvider() {
+ return new StackWalker[][] {
+ new StackWalker[] { WALKERS[0] },
+ new StackWalker[] { WALKERS[1] },
+ new StackWalker[] { WALKERS[2] }
+ };
+ }
+
+ @Test(dataProvider = "walkerProvider")
+ public void test(StackWalker walker) {
+ C1.call(walker, BIG_LOOP);
+ }
+
+ // line numbers are hardcoded for now.
+ // Should annotate the line numbers and auto-generated these constants
+ // for test verification instead
+ static final int BEGIN_LINE = 71; // the begin line number of approximate range.
+ static final int END_LINE = 136; // the end line number of approximate range.
+ static class C1 { // here is the begin line number of approximate range, L71.
+ public static void call(StackWalker walker, int loops) {
+ if (loops == 0) {
+ String caller = walker.walk(s ->
+ s.map(StackFrame::getClassName)
+ .filter(cn -> !cn.startsWith("sun.reflect.") && !cn.startsWith("java.lang.invoke"))
+ .skip(2).findFirst()
+ ).get();
+ assertEquals(caller, C1.class.getName());
+
+ walker.forEach(f -> C2.testEmbeddedWalker());
+ } else {
+ call(walker, --loops);
+ }
+ }
+ }
+
+ static class C2 {
+ static final StackWalker embeddedWalkers[] = new StackWalker[] {
+ StackWalker.getInstance(),
+ StackWalker.getInstance(SHOW_REFLECT_FRAMES),
+ StackWalker.getInstance(SHOW_HIDDEN_FRAMES)
+ };
+
+ public static void testEmbeddedWalker() {
+ walk(SMALL_LOOP);
+ }
+
+ static void walk(int loops) {
+ if (loops == 0) {
+ Arrays.stream(embeddedWalkers)
+ .forEach(walker -> run(walker));
+ } else {
+ walk(--loops);
+ }
+ }
+
+ static void run(StackWalker walker) {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandle handle = null;
+ try {
+ handle = lookup.findStatic(C2.class, "call",
+ MethodType.methodType(void.class, StackWalker.class));
+ handle.invoke(walker);
+ } catch(Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ static void call(StackWalker walker) {
+ String caller = walker.walk(s ->
+ s.map(StackFrame::getClassName)
+ .filter(cn -> !cn.startsWith("sun.reflect.") && !cn.startsWith("java.lang.invoke"))
+ .skip(2).findFirst()
+ ).get();
+ assertEquals(caller, C2.class.getName());
+
+ verify(walker, C1.class, "call");
+ verify(walker, C2.class, "call");
+ verify(walker, C2.class, "run");
+ verify(walker, C2.class, "walk");
+ verify(walker, C2.class, "testEmbeddedWalker");
+ } // here is the end line number of approximate range, L136.
+
+ static void verify(StackWalker walker, Class<?> c, String mn) {
+ final String fileName = "EmbeddedStackWalkTest.java";
+ walker.walk(s -> {
+ s.limit(BIG_LOOP)
+ .filter(f -> c.getName().equals(f.getClassName()) && mn.equals(f.getMethodName()))
+ .forEach(f -> {
+ assertEquals(f.getFileName().get(), fileName);
+ int line = f.getLineNumber().getAsInt();
+ assertTrue(line >= BEGIN_LINE && line <= END_LINE);
+
+ StackTraceElement st = f.toStackTraceElement();
+ assertEquals(c.getName(), st.getClassName());
+ assertEquals(mn, st.getMethodName());
+ assertEquals(st.getFileName(), fileName);
+ line = st.getLineNumber();
+ assertTrue(line >= BEGIN_LINE && line <= END_LINE);
+ });
+ return null;
+ });
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/GetCallerClassTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8140450
+ * @summary Basic test for StackWalker.getCallerClass()
+ * @run main/othervm -XX:-MemberNameInStackFrame GetCallerClassTest
+ * @run main/othervm -XX:+MemberNameInStackFrame GetCallerClassTest
+ * @run main/othervm GetCallerClassTest sm
+ */
+
+import static java.lang.StackWalker.Option.*;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.List;
+
+public class GetCallerClassTest {
+ private final StackWalker walker;
+ private final boolean expectUOE;
+
+ public GetCallerClassTest(StackWalker sw, boolean expect) {
+ this.walker = sw;
+ this.expectUOE = expect;
+ }
+ public static void main(String... args) throws Exception {
+ if (args.length > 0 && args[0].equals("sm")) {
+ PermissionCollection perms = new Permissions();
+ perms.add(new StackFramePermission("retainClassReference"));
+ Policy.setPolicy(new Policy() {
+ @Override
+ public boolean implies(ProtectionDomain domain, Permission p) {
+ return perms.implies(p);
+ }
+ });
+ System.setSecurityManager(new SecurityManager());
+ }
+ new GetCallerClassTest(StackWalker.getInstance(), true).test();
+ new GetCallerClassTest(StackWalker.getInstance(RETAIN_CLASS_REFERENCE), false).test();
+ }
+
+ public void test() {
+ new TopLevelCaller().run();
+ new Nested().createNestedCaller().run();
+ new InnerClassCaller().run();
+ new ReflectionTest().run();
+
+ List<Thread> threads = Arrays.asList(
+ new Thread(new TopLevelCaller()),
+ new Thread(new Nested().createNestedCaller()),
+ new Thread(new InnerClassCaller()),
+ new Thread(new ReflectionTest())
+ );
+ threads.stream().forEach(Thread::start);
+ threads.stream().forEach(t -> {
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ public static void staticGetCallerClass(StackWalker stackWalker,
+ Class<?> expected,
+ boolean expectUOE) {
+ try {
+ Class<?> c = stackWalker.getCallerClass();
+ assertEquals(c, expected);
+ if (expectUOE) { // Should have thrown
+ throw new RuntimeException("Didn't get expected exception");
+ }
+ } catch (RuntimeException e) { // also catches UOE
+ if (expectUOE && causeIsUOE(e)) {
+ return; /* expected */
+ }
+ System.err.println("Unexpected exception:");
+ throw e;
+ }
+ }
+
+ public static void reflectiveGetCallerClass(StackWalker stackWalker,
+ Class<?> expected,
+ boolean expectUOE) {
+ try {
+ Method m = StackWalker.class.getMethod("getCallerClass");
+ Class<?> c = (Class<?>) m.invoke(stackWalker);
+ assertEquals(c, expected);
+ if (expectUOE) { // Should have thrown
+ throw new RuntimeException("Didn't get expected exception");
+ }
+ } catch (Throwable e) {
+ if (expectUOE && causeIsUOE(e)) {
+ return; /* expected */
+ }
+ System.err.println("Unexpected exception:");
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void methodHandleGetCallerClass(StackWalker stackWalker,
+ Class<?> expected,
+ boolean expectUOE) {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",
+ MethodType.methodType(Class.class));
+ Class<?> c = (Class<?>) mh.invokeExact(stackWalker);
+ assertEquals(c, expected);
+ if (expectUOE) { // Should have thrown
+ throw new RuntimeException("Didn't get expected exception");
+ }
+ } catch (Throwable e) {
+ if (expectUOE && causeIsUOE(e)) {
+ return; /* expected */
+ }
+ System.err.println("Unexpected exception:");
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void assertEquals(Class<?> c, Class<?> expected) {
+ if (expected != c) {
+ throw new RuntimeException(c + " != " + expected);
+ }
+ }
+
+ /** Is there an UnsupportedOperationException in there? */
+ public static boolean causeIsUOE(Throwable t) {
+ while (t != null) {
+ if (t instanceof UnsupportedOperationException) {
+ return true;
+ }
+ t = t.getCause();
+ }
+ return false;
+ }
+
+ class TopLevelCaller implements Runnable {
+ public void run() {
+ GetCallerClassTest.staticGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.reflectiveGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.methodHandleGetCallerClass(walker, this.getClass(), expectUOE);
+ }
+ }
+
+ class Nested {
+ NestedClassCaller createNestedCaller() { return new NestedClassCaller(); }
+ class NestedClassCaller implements Runnable {
+ public void run() {
+ GetCallerClassTest.staticGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.reflectiveGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.methodHandleGetCallerClass(walker, this.getClass(), expectUOE);
+ }
+ }
+ }
+
+ class InnerClassCaller implements Runnable {
+ public void run() {
+ new Inner().test();
+ }
+ class Inner {
+ void test() {
+ GetCallerClassTest.staticGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.reflectiveGetCallerClass(walker, this.getClass(), expectUOE);
+ GetCallerClassTest.methodHandleGetCallerClass(walker, this.getClass(), expectUOE);
+ }
+ }
+ }
+
+ class ReflectionTest implements Runnable {
+ final MethodType methodType =
+ MethodType.methodType(void.class, StackWalker.class, Class.class, boolean.class);
+
+ public void run() {
+ callMethodHandle();
+ callMethodHandleRefl();
+ callMethodInvoke();
+ callMethodInvokeRefl();
+ }
+ void callMethodHandle() {
+ MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+ try {
+ MethodHandle mh = lookup.findStatic(GetCallerClassTest.class,
+ "staticGetCallerClass",
+ methodType);
+ mh.invokeExact(walker, ReflectionTest.class, expectUOE);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+ void callMethodHandleRefl() {
+ MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+ try {
+ MethodHandle mh = lookup.findStatic(GetCallerClassTest.class,
+ "reflectiveGetCallerClass",
+ methodType);
+ mh.invokeExact(walker, ReflectionTest.class, expectUOE);
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+ void callMethodInvoke() {
+ try {
+ Method m = GetCallerClassTest.class.getMethod("staticGetCallerClass",
+ StackWalker.class, Class.class, boolean.class);
+ m.invoke(null, walker, ReflectionTest.class, expectUOE);
+ } catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ void callMethodInvokeRefl() {
+ try {
+ Method m = GetCallerClassTest.class.getMethod("reflectiveGetCallerClass",
+ StackWalker.class, Class.class, boolean.class);
+ m.invoke(null, walker, ReflectionTest.class, expectUOE);
+ } catch (UnsupportedOperationException e) {
+ throw e;
+ } catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/HiddenFrames.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020968
+ * @summary Basic test for hidden frames
+ * @run main HiddenFrames
+ */
+
+import java.lang.StackWalker.Option;
+import java.lang.StackWalker.StackFrame;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+public class HiddenFrames {
+ public static void main(String... args) throws Exception {
+ new HiddenFrames().test();
+ new HiddenFrames(Option.SHOW_REFLECT_FRAMES).test();
+ new HiddenFrames(Option.SHOW_HIDDEN_FRAMES).test();
+ }
+
+ private final Option option;
+ private final StackWalker walker;
+ private final List<StackFrame> lambdas = new ArrayList<>();
+ private final List<StackFrame> reflects = new ArrayList<>();
+
+ HiddenFrames() {
+ this.option = null;
+ this.walker = StackWalker.getInstance();
+ }
+ HiddenFrames(Option option) {
+ this.option = option;
+ this.walker = StackWalker.getInstance(option);
+ }
+
+ void test() throws Exception {
+ walk();
+ walkFromReflection();
+ }
+
+ void walk() {
+ Stream.of(0).forEach(i -> walker.walk(s ->
+ {
+ s.forEach(this::checkFrame);
+ return null;
+ }));
+
+ // only check hidden frames but not reflection frames
+ // walk is not invoked via reflection
+ if (option == null && !lambdas.isEmpty()) {
+ throw new RuntimeException("Hidden frames are shown");
+ }
+
+ if (option == Option.SHOW_HIDDEN_FRAMES && lambdas.isEmpty()) {
+ throw new RuntimeException("No hidden Lambda frame");
+ }
+ }
+
+ void walkFromReflection() throws Exception {
+ Method m = HiddenFrames.class.getDeclaredMethod("walk");
+ m.invoke(this);
+
+ if (option == null && !lambdas.isEmpty()) {
+ throw new RuntimeException("Hidden frames are shown");
+ }
+
+ if (option == Option.SHOW_HIDDEN_FRAMES && lambdas.isEmpty()) {
+ throw new RuntimeException("No hidden Lambda frame");
+ }
+
+ if (option != null && reflects.isEmpty()) {
+ throw new RuntimeException("No reflection frame");
+ }
+ }
+
+ void checkFrame(StackFrame frame) {
+ String cn = frame.getClassName();
+ if (cn.startsWith("java.lang.reflect.") || cn.startsWith("sun.reflect.")) {
+ reflects.add(frame);
+ }
+ if (cn.contains("$$Lambda$")) {
+ lambdas.add(frame);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020968
+ * @summary Sanity test for locals and operands
+ * @run main LocalsAndOperands
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.lang.reflect.*;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class LocalsAndOperands {
+ static Class<?> liveStackFrameClass;
+ static Class<?> primitiveValueClass;
+ static StackWalker extendedWalker;
+ static Method getLocals;
+ static Method getOperands;
+ static Method getMonitors;
+ static Method primitiveType;
+ public static void main(String... args) throws Exception {
+ liveStackFrameClass = Class.forName("java.lang.LiveStackFrame");
+ primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue");
+
+ getLocals = liveStackFrameClass.getDeclaredMethod("getLocals");
+ getLocals.setAccessible(true);
+
+ getOperands = liveStackFrameClass.getDeclaredMethod("getStack");
+ getOperands.setAccessible(true);
+
+ getMonitors = liveStackFrameClass.getDeclaredMethod("getMonitors");
+ getMonitors.setAccessible(true);
+
+ primitiveType = primitiveValueClass.getDeclaredMethod("type");
+ primitiveType.setAccessible(true);
+
+ Method method = liveStackFrameClass.getMethod("getStackWalker");
+ method.setAccessible(true);
+ extendedWalker = (StackWalker) method.invoke(null);
+ new LocalsAndOperands(extendedWalker, true).test();
+
+ // no access to local and operands.
+ new LocalsAndOperands(StackWalker.getInstance(), false).test();
+ }
+
+ private final StackWalker walker;
+ private final boolean extended;
+ LocalsAndOperands(StackWalker walker, boolean extended) {
+ this.walker = walker;
+ this.extended = extended;
+ }
+
+ synchronized void test() throws Exception {
+ int x = 10;
+ char c = 'z';
+ String hi = "himom";
+ long l = 1000000L;
+ double d = 3.1415926;
+
+ List<StackWalker.StackFrame> frames = walker.walk(s -> s.collect(Collectors.toList()));
+ if (extended) {
+ for (StackWalker.StackFrame f : frames) {
+ System.out.println("frame: " + f);
+ Object[] locals = (Object[]) getLocals.invoke(f);
+ for (int i = 0; i < locals.length; i++) {
+ System.out.format("local %d: %s type %s%n", i, locals[i], type(locals[i]));
+ }
+
+ Object[] operands = (Object[]) getOperands.invoke(f);
+ for (int i = 0; i < operands.length; i++) {
+ System.out.format("operand %d: %s type %s%n", i, operands[i], type(operands[i]));
+ }
+
+ Object[] monitors = (Object[]) getMonitors.invoke(f);
+ for (int i = 0; i < monitors.length; i++) {
+ System.out.format("monitor %d: %s%n", i, monitors[i]);
+ }
+ }
+ } else {
+ for (StackFrame f : frames) {
+ if (liveStackFrameClass.isInstance(f))
+ throw new RuntimeException("should not be LiveStackFrame");
+ }
+ }
+ }
+
+ String type(Object o) throws Exception {
+ if (primitiveValueClass.isInstance(o)) {
+ char c = (char)primitiveType.invoke(o);
+ return String.valueOf(c);
+ } else {
+ return o.getClass().getName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/MultiThreadStackWalk.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.lang.StackWalker.StackFrame;
+import static java.lang.StackWalker.Option.*;
+
+
+/**
+ * @test
+ * @bug 8140450
+ * @summary This test will walk the stack using different methods, called
+ * from several threads running concurrently.
+ * Except in the case of MTSTACKSTREAM - which takes a snapshot
+ * of the stack before walking, all the methods only allow to
+ * walk the current thread stack.
+ * @run main/othervm MultiThreadStackWalk
+ * @author danielfuchs
+ */
+public class MultiThreadStackWalk {
+
+ static Set<String> infrastructureClasses = new TreeSet<>(Arrays.asList(
+ "sun.reflect.NativeMethodAccessorImpl",
+ "sun.reflect.DelegatingMethodAccessorImpl",
+ "java.lang.reflect.Method",
+ "com.sun.javatest.regtest.MainWrapper$MainThread",
+ "java.lang.Thread"
+ ));
+
+
+ static final List<Class<?>> streamPipelines = Arrays.asList(
+ classForName("java.util.stream.AbstractPipeline"),
+ classForName("java.util.stream.TerminalOp")
+ );
+
+ static Class<?> classForName(String name) {
+ try {
+ return Class.forName(name);
+ } catch (ClassNotFoundException e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static boolean isStreamPipeline(Class<?> clazz) {
+ for (Class<?> c : streamPipelines) {
+ if (c.isAssignableFrom(clazz)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * An object that contains variables pertaining to the execution
+ * of the test within one thread.
+ * A small amount of those variable are shared with sub threads when
+ * the stack walk is executed in parallel - that is when spliterators
+ * obtained from trySplit are handed over to an instance of SplitThread
+ * in order to parallelize thread walking.
+ * @see WalkThread#handOff(MultiThreadStackWalk.Env, java.util.Spliterator, boolean, boolean)
+ * @see Env#split(MultiThreadStackWalk.Env)
+ */
+ public static class Env {
+ final AtomicLong frameCounter; // private: the counter for the current thread.
+ final long checkMarkAt; // constant: the point at which we expect to
+ // find the marker in consume()
+ final long max; // constant: the maximum number of recursive
+ // calls to Call.
+ final AtomicBoolean debug ; // shared: whether debug is active for the
+ // instance of Test from which this instance
+ // of Env was spawned
+ final AtomicLong markerCalled; // shared: whether the marker was reached
+ final AtomicLong maxReached; // shared: whether max was reached
+ final Set<String> unexpected; // shared: list of unexpected infrastructure
+ // classes encountered after max is reached
+
+ public Env(long total, long markAt, AtomicBoolean debug) {
+ this.debug = debug;
+ frameCounter = new AtomicLong();
+ maxReached = new AtomicLong();
+ unexpected = Collections.synchronizedSet(new TreeSet<>());
+ this.max = total+2;
+ this.checkMarkAt = total - markAt + 1;
+ this.markerCalled = new AtomicLong();
+ }
+
+ // Used when delegating part of the stack walking to a sub thread
+ // see WalkThread.handOff.
+ private Env(Env orig, long start) {
+ debug = orig.debug;
+ frameCounter = new AtomicLong(start);
+ maxReached = orig.maxReached;
+ unexpected = orig.unexpected;
+ max = orig.max;
+ checkMarkAt = orig.checkMarkAt;
+ markerCalled = orig.markerCalled;
+ }
+
+ // The stack walk consumer method, where all the checks are
+ // performed.
+ public void consume(StackFrame sfi) {
+ if (frameCounter.get() == 0 && isStreamPipeline(sfi.getDeclaringClass())) {
+ return;
+ }
+
+ final long count = frameCounter.getAndIncrement();
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Declaring class[")
+ .append(count)
+ .append("]: ")
+ .append(sfi.getDeclaringClass());
+ builder.append('\n');
+ builder.append("\t")
+ .append(sfi.getClassName())
+ .append(".")
+ .append(sfi.toStackTraceElement().getMethodName())
+ .append(sfi.toStackTraceElement().isNativeMethod()
+ ? "(native)"
+ : "(" + sfi.toStackTraceElement().getFileName()
+ +":"+sfi.toStackTraceElement().getLineNumber()+")");
+ builder.append('\n');
+ if (debug.get()) {
+ System.out.print("[debug] " + builder.toString());
+ builder.setLength(0);
+ }
+ if (count == max) {
+ maxReached.incrementAndGet();
+ }
+ if (count == checkMarkAt) {
+ if (sfi.getDeclaringClass() != MultiThreadStackWalk.Marker.class) {
+ throw new RuntimeException("Expected Marker at " + count
+ + ", found " + sfi.getDeclaringClass());
+ }
+ } else {
+ if (count <= 0 && sfi.getDeclaringClass() != MultiThreadStackWalk.Call.class) {
+ throw new RuntimeException("Expected Call at " + count
+ + ", found " + sfi.getDeclaringClass());
+ } else if (count > 0 && count < max && sfi.getDeclaringClass() != MultiThreadStackWalk.Test.class) {
+ throw new RuntimeException("Expected Test at " + count
+ + ", found " + sfi.getDeclaringClass());
+ } else if (count == max && sfi.getDeclaringClass() != MultiThreadStackWalk.class) {
+ throw new RuntimeException("Expected MultiThreadStackWalk at "
+ + count + ", found " + sfi.getDeclaringClass());
+ } else if (count == max && !sfi.toStackTraceElement().getMethodName().equals("runTest")) {
+ throw new RuntimeException("Expected runTest method at "
+ + count + ", found " + sfi.toStackTraceElement().getMethodName());
+ } else if (count == max+1) {
+ if (sfi.getDeclaringClass() != MultiThreadStackWalk.WalkThread.class) {
+ throw new RuntimeException("Expected MultiThreadStackWalk at "
+ + count + ", found " + sfi.getDeclaringClass());
+ }
+ if (count == max && !sfi.toStackTraceElement().getMethodName().equals("run")) {
+ throw new RuntimeException("Expected main method at "
+ + count + ", found " + sfi.toStackTraceElement().getMethodName());
+ }
+ } else if (count > max+1) {
+ // expect JTreg infrastructure...
+ if (!infrastructureClasses.contains(sfi.getDeclaringClass().getName())) {
+ System.err.println("**** WARNING: encountered unexpected infrastructure class at "
+ + count +": " + sfi.getDeclaringClass().getName());
+ unexpected.add(sfi.getDeclaringClass().getName());
+ }
+ }
+ }
+ if (count == 100) {
+ // Maybe we should had some kind of checking inside that lambda
+ // too. For the moment we should be satisfied if it doesn't throw
+ // any exception and doesn't make the outer walk fail...
+ StackWalker.getInstance(RETAIN_CLASS_REFERENCE).forEach(x -> {
+ StackTraceElement st = x.toStackTraceElement();
+ StringBuilder b = new StringBuilder();
+ b.append("*** inner walk: ")
+ .append(x.getClassName())
+ .append(st == null ? "- no stack trace element -" :
+ ("." + st.getMethodName()
+ + (st.isNativeMethod() ? "(native)" :
+ "(" + st.getFileName()
+ + ":" + st.getLineNumber() + ")")))
+ .append('\n');
+ if (debug.get()) {
+ System.out.print(b.toString());
+ b.setLength(0);
+ }
+ });
+ }
+ }
+ }
+
+ public interface Call {
+ enum WalkType {
+ WALKSTACK, // use Thread.walkStack
+ }
+ default WalkType getWalkType() { return WalkType.WALKSTACK;}
+ default void walk(Env env) {
+ WalkType walktype = getWalkType();
+ System.out.println("Thread "+ Thread.currentThread().getName()
+ +" starting walk with " + walktype);
+ switch(walktype) {
+ case WALKSTACK:
+ StackWalker.getInstance(RETAIN_CLASS_REFERENCE)
+ .forEach(env::consume);
+ break;
+ default:
+ throw new InternalError("Unknown walk type: " + walktype);
+ }
+ }
+ default void call(Env env, Call next, int total, int current, int markAt) {
+ if (current < total) {
+ next.call(env, next, total, current+1, markAt);
+ }
+ }
+ }
+
+ public static class Marker implements Call {
+ final WalkType walkType;
+ Marker(WalkType walkType) {
+ this.walkType = walkType;
+ }
+ @Override
+ public WalkType getWalkType() {
+ return walkType;
+ }
+
+ @Override
+ public void call(Env env, Call next, int total, int current, int markAt) {
+ env.markerCalled.incrementAndGet();
+ if (current < total) {
+ next.call(env, next, total, current+1, markAt);
+ } else {
+ next.walk(env);
+ }
+ }
+ }
+
+ public static class Test implements Call {
+ final Marker marker;
+ final WalkType walkType;
+ final AtomicBoolean debug;
+ Test(WalkType walkType) {
+ this.walkType = walkType;
+ this.marker = new Marker(walkType);
+ this.debug = new AtomicBoolean();
+ }
+ @Override
+ public WalkType getWalkType() {
+ return walkType;
+ }
+ @Override
+ public void call(Env env, Call next, int total, int current, int markAt) {
+ if (current < total) {
+ int nexti = current + 1;
+ Call nextObj = nexti==markAt ? marker : next;
+ nextObj.call(env, next, total, nexti, markAt);
+ } else {
+ walk(env);
+ }
+ }
+ }
+
+ public static Env runTest(Test test, int total, int markAt) {
+ Env env = new Env(total, markAt, test.debug);
+ test.call(env, test, total, 0, markAt);
+ return env;
+ }
+
+ public static void checkTest(Env env, Test test) {
+ String threadName = Thread.currentThread().getName();
+ System.out.println(threadName + ": Marker called: " + env.markerCalled.get());
+ System.out.println(threadName + ": Max reached: " + env.maxReached.get());
+ System.out.println(threadName + ": Frames consumed: " + env.frameCounter.get());
+ if (env.markerCalled.get() == 0) {
+ throw new RuntimeException(Thread.currentThread().getName() + ": Marker was not called.");
+ }
+ if (env.markerCalled.get() > 1) {
+ throw new RuntimeException(Thread.currentThread().getName()
+ + ": Marker was called more than once: " + env.maxReached.get());
+ }
+ if (!env.unexpected.isEmpty()) {
+ System.out.flush();
+ System.err.println("Encountered some unexpected infrastructure classes below 'main': "
+ + env.unexpected);
+ }
+ if (env.maxReached.get() == 0) {
+ throw new RuntimeException(Thread.currentThread().getName()
+ + ": max not reached");
+ }
+ if (env.maxReached.get() > 1) {
+ throw new RuntimeException(Thread.currentThread().getName()
+ + ": max was reached more than once: " + env.maxReached.get());
+ }
+ }
+
+ static class WalkThread extends Thread {
+ final static AtomicLong walkersCount = new AtomicLong();
+ Throwable failed = null;
+ final Test test;
+ public WalkThread(Test test) {
+ super("WalkThread[" + walkersCount.incrementAndGet() + ", type="
+ + test.getWalkType() + "]");
+ this.test = test;
+ }
+
+ public void run() {
+ try {
+ Env env = runTest(test, 2000, 10);
+ //waitWalkers(env);
+ checkTest(env, test);
+ } catch(Throwable t) {
+ failed = t;
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ WalkThread[] threads = new WalkThread[Call.WalkType.values().length*3];
+ Throwable failed = null;
+ for (int i=0; i<threads.length; i++) {
+ Test test = new Test(Call.WalkType.values()[i%Call.WalkType.values().length]);
+ threads[i] = new WalkThread(test);
+ }
+ for (int i=0; i<threads.length; i++) {
+ threads[i].start();
+ }
+ for (int i=0; i<threads.length; i++) {
+ threads[i].join();
+ if (failed == null) failed = threads[i].failed;
+ else if (threads[i].failed == null) {
+ failed.addSuppressed(threads[i].failed);
+ }
+ }
+ if (failed != null) {
+ throw failed;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/SanityTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8140450
+ * @summary Sanity test for exception cases
+ * @run testng SanityTest
+ */
+
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+public class SanityTest {
+ @Test
+ public static void testNPE() {
+ try {
+ StackWalker sw = StackWalker.getInstance((Set<StackWalker.Option>) null);
+ throw new RuntimeException("NPE expected");
+ } catch (NullPointerException e) {}
+
+ try {
+ StackWalker sw = StackWalker.getInstance((StackWalker.Option) null);
+ throw new RuntimeException("NPE expected");
+ } catch (NullPointerException e) {}
+ }
+
+ @Test
+ public static void testUOE() {
+ try {
+ StackWalker.getInstance().getCallerClass();
+ throw new RuntimeException("UOE expected");
+ } catch (UnsupportedOperationException expected) {}
+ }
+
+ @Test
+ public static void testInvalidEstimateDepth() {
+ try {
+ StackWalker sw = StackWalker.getInstance(Collections.emptySet(), 0);
+ throw new RuntimeException("Illegal estimateDepth should throw IAE");
+ } catch (IllegalArgumentException e) {}
+ }
+
+ @Test
+ public static void testNullFuncation() {
+ try {
+ StackWalker.getInstance().walk(null);
+ throw new RuntimeException("NPE expected");
+ } catch (NullPointerException e) {}
+ }
+
+ @Test
+ public static void testNullConsumer() {
+ try {
+ StackWalker.getInstance().forEach(null);
+ throw new RuntimeException("NPE expected");
+ } catch (NullPointerException e) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/SecurityExceptions.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test 8020968
+ * @summary Test security permission check
+ * @run main/othervm/java.security.policy=noperms.policy SecurityExceptions true
+ * @run main/othervm/java.security.policy=stackwalk.policy SecurityExceptions false
+ */
+public class SecurityExceptions {
+ public static void main(String[] args) {
+ boolean expectException = Boolean.parseBoolean(args[0]);
+
+ StackWalker sw = StackWalker.getInstance();
+
+ try {
+ sw = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ if (expectException) {
+ throw new RuntimeException("Expected SecurityException, but none thrown");
+ }
+ } catch (SecurityException e) {
+ if (!expectException) {
+ System.err.println("Unexpected security exception:");
+ throw e;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/StackRecorderUtil.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.StackWalker.Option;
+import java.lang.StackWalker.StackFrame;
+import java.util.*;
+
+/**
+ * Utility class for recording a stack trace for later comparison to
+ * StackWalker results.
+ *
+ * StackTraceElement comparison does not include line number, isNativeMethod
+ */
+public class StackRecorderUtil implements Iterable<StackRecorderUtil.TestFrame> {
+ private List<TestFrame> testFrames = new LinkedList();
+
+ private boolean compareClasses;
+ private boolean compareClassNames = true;
+ private boolean compareMethodNames = true;
+ private boolean compareSTEs;
+
+ public StackRecorderUtil(Set<StackWalker.Option> swOptions) {
+ compareClasses = swOptions.contains(Option.RETAIN_CLASS_REFERENCE);
+ compareSTEs = true;
+ }
+
+ /**
+ * Add a method call to this recorded stack.
+ */
+ public void add(Class declaringClass, String methodName, String fileName) {
+ testFrames.add(0, new TestFrame(declaringClass, methodName, fileName));
+ }
+
+ public int frameCount() { return testFrames.size(); }
+
+ /**
+ * Compare the given StackFrame returned from the StackWalker to the
+ * recorded frame at the given index.
+ *
+ * Tests for equality, as well as functional correctness with respect to
+ * the StackWalker's options (e.g. throws or doesn't throw exceptions)
+ */
+ public void compareFrame(int index, StackFrame sf) {
+ TestFrame tf = testFrames.get(index);
+ if (compareClasses) {
+ if (!tf.declaringClass.equals(sf.getDeclaringClass())) {
+ throw new RuntimeException("Expected class: " +
+ tf.declaringClass.toString() + ", but got: " +
+ sf.getDeclaringClass().toString());
+ }
+ } else {
+ boolean caught = false;
+ try {
+ sf.getDeclaringClass();
+ } catch (UnsupportedOperationException e) {
+ caught = true;
+ }
+ if (!caught) {
+ throw new RuntimeException("StackWalker did not have " +
+ "RETAIN_CLASS_REFERENCE Option, but did not throw " +
+ "UnsupportedOperationException");
+ }
+ }
+
+ if (compareClassNames && !tf.className().equals(sf.getClassName())) {
+ throw new RuntimeException("Expected class name: " + tf.className() +
+ ", but got: " + sf.getClassName());
+ }
+ if (compareMethodNames && !tf.methodName.equals(sf.getMethodName())) {
+ throw new RuntimeException("Expected method name: " + tf.methodName +
+ ", but got: " + sf.getMethodName());
+ }
+ if (compareSTEs) {
+ StackTraceElement ste = sf.toStackTraceElement();
+ if (!(ste.getClassName().equals(tf.className()) &&
+ ste.getMethodName().equals(tf.methodName)) &&
+ ste.getFileName().equals(tf.fileName)) {
+ throw new RuntimeException("Expected StackTraceElement info: " +
+ tf + ", but got: " + ste);
+ }
+ if (!Objects.equals(ste.getClassName(), sf.getClassName())
+ || !Objects.equals(ste.getMethodName(), sf.getMethodName())
+ || !Objects.equals(ste.getFileName(), sf.getFileName().orElse(null))
+ || !Objects.equals(ste.getLineNumber(), sf.getLineNumber().orElse(-1))
+ || !Objects.equals(ste.isNativeMethod(), sf.isNativeMethod())) {
+ throw new RuntimeException("StackFrame and StackTraceElement differ: " +
+ "sf=" + sf + ", ste=" + ste);
+ }
+ }
+ }
+
+ public Iterator<TestFrame> iterator() {
+ return testFrames.iterator();
+ }
+
+ /**
+ * Class used to record stack frame information.
+ */
+ public static class TestFrame {
+ public Class declaringClass;
+ public String methodName;
+ public String fileName = null;
+
+ public TestFrame (Class declaringClass, String methodName, String fileName) {
+ this.declaringClass = declaringClass;
+ this.methodName = methodName;
+ this.fileName = fileName;
+ }
+ public String className() {
+ return declaringClass.getName();
+ }
+ public String toString() {
+ return "TestFrame: " + className() + "." + methodName +
+ (fileName == null ? "" : "(" + fileName + ")");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/StackStreamState.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020968
+ * @summary Basic test for Stream<StackFrame> state
+ * @run main StackStreamState
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.util.stream.Stream;
+
+public class StackStreamState {
+ public static void main(String... args) {
+ StackStreamState test = new StackStreamState();
+ test.testStatic();
+ test.testInstance();
+ test.testLocal();
+ }
+
+ private static Stream<StackFrame> staticStream;
+ private Stream<StackFrame> instanceStream;
+ private final StackWalker walker = StackWalker.getInstance();
+ void testStatic() {
+ walker.walk(s -> {
+ staticStream = s;
+ return null;
+ });
+ checkStreamState(staticStream);
+ }
+ void testInstance() {
+ walker.walk(s -> {
+ instanceStream = s;
+ return null;
+ });
+ checkStreamState(instanceStream);
+ }
+ void testLocal() {
+ Stream<StackFrame> stream = walker.walk(s -> {
+ return s;
+ });
+ checkStreamState(stream);
+ }
+ void checkStreamState(Stream<StackFrame> stream) {
+ try {
+ stream.count();
+ throw new RuntimeException("IllegalStateException not thrown");
+ } catch (IllegalStateException e) {
+ System.out.println("Got expected IllegalStateException: " + e.getMessage());
+ e.printStackTrace(System.out);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/StackStreamTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.lang.StackWalker.Option.*;
+import java.lang.StackWalker.StackFrame;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+/**
+ * @test
+ * @bug 8140450
+ * @summary Stack Stream Test
+ * @run main/othervm StackStreamTest
+ */
+public class StackStreamTest {
+ public static void main(String[] argv) throws Exception {
+ new StackStreamTest().test();
+ }
+
+ private static Logger logger = Logger.getLogger("stackstream");
+ public StackStreamTest() {
+ }
+
+ public void test() {
+ A.a();
+ }
+ static class A {
+ public static void a() {
+ B.b();
+ }
+ }
+ static class B {
+ public static void b() {
+ C.c();
+ }
+ }
+ static class C {
+ public static void c() {
+ D.d();
+ }
+ }
+ static class D {
+ public static void d() {
+ E.e();
+ }
+ }
+ static class E {
+ public static void e() {
+ F.f();
+ }
+ }
+ static class F {
+ public static void f() {
+ logger.severe("log message");
+ G.g();
+ new K().k();
+ }
+ }
+
+ private static boolean isTestClass(StackFrame f) {
+ // Filter jtreg frames from the end of the stack
+ return f.getClassName().startsWith("StackStreamTest");
+ }
+
+ static class G {
+ static StackWalker STE_WALKER = StackWalker.getInstance();
+ static StackWalker DEFAULT_WALKER = StackWalker.getInstance();
+
+ private static final List<String> GOLDEN_CLASS_NAMES =
+ Arrays.asList("StackStreamTest$G",
+ "StackStreamTest$F",
+ "StackStreamTest$E",
+ "StackStreamTest$D",
+ "StackStreamTest$C",
+ "StackStreamTest$B",
+ "StackStreamTest$A",
+ "StackStreamTest",
+ "StackStreamTest");
+ private static final List<String> GOLDEN_METHOD_NAMES =
+ Arrays.asList("g", "f", "e", "d", "c", "b", "a", "test", "main");
+
+
+ public static void g() {
+
+ System.out.println("Thread dump");
+ Thread.dumpStack();
+
+ caller();
+ firstFrame();
+
+ // Check class names
+ System.out.println("check class names");
+ List<String> sfs = DEFAULT_WALKER.walk(s -> {
+ return s.filter(StackStreamTest::isTestClass)
+ .map(StackFrame::getClassName)
+ .collect(Collectors.toList());
+ });
+ equalsOrThrow("class names", sfs, GOLDEN_CLASS_NAMES);
+
+ // Check method names
+ System.out.println("methodNames()");
+ sfs = DEFAULT_WALKER.walk(s -> {
+ return s.filter(StackStreamTest::isTestClass)
+ .map(StackFrame::getMethodName)
+ .collect(Collectors.toList());}
+ );
+ equalsOrThrow("method names", sfs, GOLDEN_METHOD_NAMES);
+
+ Exception exc = new Exception("G.g stack");
+ exc.printStackTrace();
+
+ System.out.println("Stream of StackTraceElement");
+ StackWalker.getInstance()
+ .walk(s ->
+ {
+ s.map(StackFrame::toStackTraceElement)
+ .forEach(ste -> System.out.println("STE: " + ste));
+ return null;
+ });
+
+ // Do we need this?
+ System.out.println("Collect StackTraceElement");
+ List<StackTraceElement> stacktrace = STE_WALKER.walk(s ->
+ {
+ // Filter out jtreg frames
+ return s.filter(StackStreamTest::isTestClass)
+ .collect(Collectors.mapping(StackFrame::toStackTraceElement, Collectors.toList()));
+ });
+ int i=0;
+ for (StackTraceElement s : stacktrace) {
+ System.out.format(" %d: %s%n", i++, s);
+ }
+
+ // Check STEs for correctness
+ checkStackTraceElements(GOLDEN_CLASS_NAMES, GOLDEN_METHOD_NAMES, stacktrace);
+ }
+
+ static void checkStackTraceElements(List<String> classNames,
+ List<String> methodNames,
+ List<StackTraceElement> stes) {
+ if (classNames.size() != methodNames.size() ) {
+ throw new RuntimeException("Test error: classNames and methodNames should be same size");
+ }
+ if (classNames.size() != stes.size()) {
+ dumpSTEInfo(classNames, methodNames, stes);
+ throw new RuntimeException("wrong number of elements in stes");
+ }
+ for (int i = 0; i < classNames.size() ; i++) {
+ if (!classNames.get(i).equals(stes.get(i).getClassName()) ||
+ !methodNames.get(i).equals(stes.get(i).getMethodName())) {
+ dumpSTEInfo(classNames, methodNames, stes);
+ throw new RuntimeException("class & method names don't match");
+ }
+ }
+ }
+
+ static void dumpSTEInfo(List<String> classNames, List<String> methodNames,
+ List<StackTraceElement> stes) {
+ System.out.println("Observed class, method names:");
+ for (StackTraceElement ste : stes) {
+ System.out.println(" " + ste.getClassName() + ", " + ste.getMethodName());
+ }
+ System.out.println("Expected class, method names:");
+ for (int i = 0; i < classNames.size(); i++) {
+ System.out.println(" " + classNames.get(i) + ", " + methodNames.get(i));
+ }
+ }
+
+ static void firstFrame() {
+ System.out.println("first frame()");
+ StackWalker sw = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
+ sw.forEach(e -> {
+ System.out.println(e.getClassName() + "," + e.getMethodName());
+ });
+ System.out.println("\n");
+ Optional<StackFrame> frame = sw.walk(s ->
+ {
+ return s.filter(e -> {
+ System.err.println(e.getClassName() + " == " +
+ e.getClassName().equals("StackStreamTest"));
+ return e.getClassName().equals("StackStreamTest");
+ }).findFirst();
+ });
+ Class<?> c = frame.get().getDeclaringClass();
+ System.out.println("\nfirst frame: " + c);
+ if (c != StackStreamTest.class) {
+ throw new RuntimeException("Unexpected first caller class " + c);
+ }
+ }
+ }
+
+ private static <T> void equalsOrThrow(String label, List<T> list, List<T> expected) {
+ System.out.println("List: " + list);
+ System.out.println("Expectd: " + list);
+ if (!list.equals(expected)) {
+ System.err.println("Observed " + label);
+ for (T s1 : list) {
+ System.out.println(" " + s1);
+ }
+ System.err.println("Expected " + label);
+ for (T s2 : expected) {
+ System.out.println(" " + s2);
+ }
+ throw new RuntimeException("Error with " + label);
+ }
+ }
+
+
+ static class K {
+ void k() {
+ k1();
+ }
+ void k1() {
+ k2();
+ }
+ void k2() {
+ k3();
+ }
+ void k3() {
+ k4();
+ }
+ void k4() {
+ k5();
+ }
+ void k5() {
+ k6();
+ }
+ void k6() {
+ k7();
+ }
+ void k7() {
+ k8();
+ }
+ void k8() {
+ k9();
+ }
+ void k9() {
+ k10();
+ }
+ void k10() {
+ k20();
+ }
+ void k20() {
+ new Caller().test();
+ }
+
+ class Caller {
+ void test() {
+ Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();
+ System.out.println("\nTesting K class : " + c);
+ Thread.dumpStack();
+ if (c != K.class) {
+ throw new RuntimeException("Unexpected caller class "+ c);
+ }
+ }
+ }
+ }
+
+ static void caller() {
+ Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();
+ System.out.println("\ncaller class : " + c);
+ if (c != G.class) {
+ throw new RuntimeException("Unexpected caller class "+ c);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/StackWalkTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static java.lang.StackWalker.Option.*;
+import java.lang.StackWalker.StackFrame;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * @test
+ * @bug 8140450
+ * @summary Stack Walk Test (use -Dseed=X to set PRNG seed)
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @compile StackRecorderUtil.java
+ * @run main/othervm StackWalkTest
+ * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest
+ * @run main/othervm StackWalkTest -random:50
+ * @run main/othervm/java.security.policy=stackwalktest.policy StackWalkTest -random:50
+ * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
+ * @run main/othervm -XX:-MemberNameInStackFrame -Dstackwalk.newThrowable=true StackWalkTest -random:50
+ * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=false StackWalkTest -random:50
+ * @run main/othervm -XX:+MemberNameInStackFrame -Dstackwalk.newThrowable=true StackWalkTest -random:50
+ * @author danielfuchs, bchristi
+ * @key randomness
+ */
+public class StackWalkTest {
+ private static boolean random = false;
+ private static boolean verbose = false;
+ private static int randomRuns = 50;
+
+ private static final int MAX_RANDOM_DEPTH = 1000;
+
+ static final Set<String> infrastructureClasses = new TreeSet<>(Arrays.asList(
+ "sun.reflect.NativeMethodAccessorImpl",
+ "sun.reflect.DelegatingMethodAccessorImpl",
+ "java.lang.reflect.Method",
+ "com.sun.javatest.regtest.MainWrapper$MainThread",
+ "com.sun.javatest.regtest.agent.MainWrapper$MainThread",
+ "java.lang.Thread"
+ ));
+ static final List<Class<?>> streamPipelines = Arrays.asList(
+ classForName("java.util.stream.AbstractPipeline"),
+ classForName("java.util.stream.TerminalOp")
+ );
+ static Class<?> classForName(String name) {
+ try {
+ return Class.forName(name);
+ } catch (ClassNotFoundException e){
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static boolean isStreamPipeline(Class<?> clazz) {
+ for (Class<?> c : streamPipelines) {
+ if (c.isAssignableFrom(clazz)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ StackRecorderUtil recorder;
+ int count = 0;
+ boolean didWalk = false;
+
+ final int estDepth;
+ final Set<StackWalker.Option> swOptions;
+
+ public StackWalkTest() {
+ this(EnumSet.noneOf(StackWalker.Option.class), -1);
+ }
+
+ public StackWalkTest(Set<StackWalker.Option> swOptions) {
+ this(swOptions, -1);
+ }
+
+ public StackWalkTest(int estimatedDepth) {
+ this(EnumSet.noneOf(StackWalker.Option.class), -1);
+ }
+
+ public StackWalkTest(Set<StackWalker.Option> swOptions, int estimatedDepth) {
+ this.swOptions = swOptions;
+ this.estDepth = estimatedDepth;
+ }
+
+ private StackWalker createStackWalker() {
+ // test all StackWalker factory methods
+ if (this.estDepth < 0) {
+ if (swOptions.isEmpty()) {
+ return StackWalker.getInstance();
+ } else {
+ return StackWalker.getInstance(swOptions);
+ }
+ }
+ return StackWalker.getInstance(swOptions, estDepth);
+ }
+ public void consume(StackFrame sf) {
+ if (count == 0 && swOptions.contains(StackWalker.Option.RETAIN_CLASS_REFERENCE)
+ && isStreamPipeline(sf.getDeclaringClass())) {
+ return;
+ }
+ if (verbose) {
+ System.out.println("\t" + sf.getClassName() + "." + sf.getMethodName());
+ }
+ if (count >= recorder.frameCount()) {
+ // We've gone past main()...
+ if (infrastructureClasses.contains(sf.getClassName())) {
+ // safe to ignore
+ return;
+ }
+ }
+ try {
+ recorder.compareFrame(count, sf);
+ } catch (IndexOutOfBoundsException e) {
+ // Extra non-infra frame in stream
+ throw new RuntimeException("extra non-infra stack frame at count "
+ + count + ": <" + sf + ">", e);
+ }
+ count++;
+ }
+
+ public class Call {
+ public void walk(int total, int markAt) {
+ recorder.add(Call.class, "walk", "StackWalkTest.java");
+ long swFrameCount = createStackWalker().walk(s -> s.count());
+
+ if (verbose) {
+ System.out.println("Call.walk() total=" + total + ", markAt=" + markAt);
+ System.out.println("recorder frames:");
+ for (StackRecorderUtil.TestFrame f : recorder) {
+ System.out.println("\t" + f.declaringClass + "." + f.methodName);
+ }
+ System.out.println("\nStackWalker recorded " + swFrameCount + " frames");
+ System.out.flush();
+ }
+ long recFrameCount = (long)recorder.frameCount();
+ if (swFrameCount < recFrameCount) {
+ throw new RuntimeException("StackWalker recorded fewer frames ("+
+ swFrameCount + ") than recorded ("+ recorder.frameCount() +
+ ") - " + "estimatedDepth set to " + estDepth);
+ }
+ if (verbose) {
+ System.out.println("StackWalker frames:");
+ }
+ createStackWalker().forEach(StackWalkTest.this::consume);
+ didWalk = true;
+ }
+ public void call(int total, int current, int markAt) {
+ recorder.add(Call.class, "call", "StackWalkTest.java");
+ if (current < total) {
+ testCall.call(total, current+1, markAt);
+ } else {
+ walk(total, markAt);
+ }
+ }
+ }
+
+ public class Marker extends Call {
+ @Override
+ public void call(int total, int current, int markAt) {
+ recorder.add(Marker.class, "call", "StackWalkTest.java");
+ if (current < total) {
+ testCall.call(total, current+1, markAt);
+ } else {
+ walk(total, markAt);
+ }
+ }
+ }
+ private Call markerCall = new Marker();
+
+ public class Test extends Call {
+ @Override
+ public void call(int total, int current, int markAt) {
+ recorder.add(Test.class, "call", "StackWalkTest.java");
+ if (current < total) {
+ int nexti = current + 1;
+ if (nexti==markAt) {
+ markerCall.call(total, nexti, markAt);
+ } else {
+ testCall.call2(total, nexti, markAt);
+ }
+ } else {
+ walk(total, markAt);
+ }
+ }
+ public void call2(int total, int current, int markAt) {
+ recorder.add(Test.class, "call2", "StackWalkTest.java");
+ if (current < total) {
+ int nexti = current + 1;
+ if (nexti==markAt) {
+ markerCall.call(total, nexti, markAt);
+ } else {
+ test2Call.call(total, nexti, markAt);
+ }
+ } else {
+ walk(total, markAt);
+ }
+ }
+ }
+ private Test testCall = new Test();
+
+ /** Inherits call() from Call */
+ public class Test2 extends Call {}
+ private Test2 test2Call = new Test2();
+
+ public void runTest(Class callerClass, String callerMethod, int stackDepth,
+ int markAt) {
+ if (didWalk) {
+ throw new IllegalStateException("StackWalkTest already used");
+ }
+ assert markAt <= stackDepth : "markAt(" + markAt + ") > stackDepth("
+ + stackDepth + ")";
+ System.out.print("runTest(" + swOptions
+ + "), estimatedDepth=" + estDepth);
+
+ recorder = new StackRecorderUtil(swOptions);
+ recorder.add(callerClass, callerMethod, "StackWalkTest.java");
+ recorder.add(StackWalkTest.class, "runTest", "StackWalkTest.java");
+
+ Test test1 = new Test();
+ test1.call(stackDepth, 0, markAt);
+
+ System.out.println(" finished");
+ if (!didWalk) {
+ throw new IllegalStateException("Test wasn't actually performed");
+ }
+ }
+
+ public static void main(String[] args) {
+ String rand = "-random";
+ String randItems = "-random:";
+ for(String arg : args) {
+ if (arg.startsWith(rand)) {
+ random = true;
+ try {
+ if(arg.startsWith(randItems)) {
+ randomRuns = Integer.valueOf(arg.substring(randItems.length()));
+ }
+ } catch(NumberFormatException e) {}
+ } else if("-verbose".equals(arg)) {
+ verbose = true;
+ }
+ }
+ if (random) {
+ Random rng = RandomFactory.getRandom();
+ for (int iters = 0; iters < randomRuns; iters++) {
+ Set<StackWalker.Option> opts = new HashSet<>();
+ if (rng.nextBoolean()) {
+ opts.add(RETAIN_CLASS_REFERENCE);
+ }
+
+ int depth = 1 + rng.nextInt(MAX_RANDOM_DEPTH);
+
+ StackWalkTest swt;
+ if (rng.nextBoolean() && depth > 1) {
+ // Test that specifying an estimatedDepth doesn't prevent
+ // full stack traversal
+ swt = new StackWalkTest(opts, 1+rng.nextInt(depth-1));
+ } else {
+ swt = new StackWalkTest(opts);
+ }
+
+ int markAt = rng.nextInt(depth+1);
+ System.out.print(depth + "@" + markAt + " ");
+ System.out.flush();
+ swt.runTest(StackWalkTest.class, "main", depth, markAt);
+ }
+ } else {
+ // Long stack, default maxDepth
+ StackWalkTest swt;
+ swt = new StackWalkTest();
+ swt.runTest(StackWalkTest.class, "main", 2000, 10);
+
+ // Long stack, matching maxDepth
+ swt = new StackWalkTest(2000);
+ swt.runTest(StackWalkTest.class, "main", 2000, 10);
+
+ // Long stack, maximum maxDepth
+ swt = new StackWalkTest(Integer.MAX_VALUE);
+ swt.runTest(StackWalkTest.class, "main", 2000, 10);
+
+ //
+ // Single batch
+ //
+ swt = new StackWalkTest(); // default maxDepth
+ swt.runTest(StackWalkTest.class, "main", 6, 3);
+
+ swt = new StackWalkTest(4); // maxDepth < stack
+ swt.runTest(StackWalkTest.class, "main", 6, 3);
+
+ swt = new StackWalkTest(2); // maxDepth < marker
+ swt.runTest(StackWalkTest.class, "main", 6, 4);
+
+ //
+ // 2 batches
+ //
+ swt = new StackWalkTest(); // default maxDepth
+ swt.runTest(StackWalkTest.class, "main", 24, 10);
+ swt = new StackWalkTest(18); // maxDepth < stack
+ swt.runTest(StackWalkTest.class, "main", 24, 10);
+ swt = new StackWalkTest(8); // maxDepth < marker
+ swt.runTest(StackWalkTest.class, "main", 24, 10);
+
+ //
+ // 3 batch
+ //
+ swt = new StackWalkTest(); // default maxDepth
+ swt.runTest(StackWalkTest.class, "main", 60, 20);
+ swt = new StackWalkTest(35); // maxDepth < stack
+ swt.runTest(StackWalkTest.class, "main", 60, 20);
+ swt = new StackWalkTest(8); // maxDepth < marker
+ swt.runTest(StackWalkTest.class, "main", 60, 20);
+
+ //
+ // StackWalker.Options
+ //
+ swt = new StackWalkTest();
+ swt.runTest(StackWalkTest.class, "main", 50, 10);
+
+ swt = new StackWalkTest(EnumSet.of(RETAIN_CLASS_REFERENCE));
+ swt.runTest(StackWalkTest.class, "main", 80, 40);
+
+ swt = new StackWalkTest(EnumSet.of(RETAIN_CLASS_REFERENCE), 50);
+ swt.runTest(StackWalkTest.class, "main", 2000, 1048);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/VerifyStackTrace.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.EnumSet;
+import java.util.concurrent.atomic.AtomicLong;
+import java.lang.StackWalker.StackFrame;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Objects;
+
+import static java.lang.StackWalker.Option.*;
+
+/**
+ * @test
+ * @bug 8140450
+ * @summary Verify stack trace information obtained with respect to StackWalker
+ * options, when the stack contains lambdas, method handle invoke
+ * virtual calls, and reflection.
+ * @run main/othervm -XX:-MemberNameInStackFrame VerifyStackTrace
+ * @run main/othervm -XX:+MemberNameInStackFrame VerifyStackTrace
+ * @run main/othervm/java.security.policy=stackwalk.policy VerifyStackTrace
+ * @author danielfuchs
+ */
+public class VerifyStackTrace {
+
+ static interface TestCase {
+ StackWalker walker();
+ String description();
+ String expected();
+ }
+ static final class TestCase1 implements TestCase {
+ private final StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
+
+ private final String description = "StackWalker.getInstance(" +
+ "StackWalker.Option.RETAIN_CLASS_REFERENCE)";
+
+ // Note: line numbers and lambda hashes will be erased when
+ // comparing stack traces. However, the stack may change
+ // if some methods are being renamed in the code base.
+ // If the JDKcode base changes and the test fails because of that,
+ // then after validating that the actual stack trace obtained
+ // is indeed correct (no frames are skipped that shouldn't)
+ // then you can cut & paste the <-- actual --> stack printed in the
+ // test output in here:
+ private final String expected =
+ "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:209)\n" +
+ "2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:145)\n" +
+ "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:158)\n" +
+ "4: VerifyStackTrace.invoke(VerifyStackTrace.java:188)\n" +
+ "5: VerifyStackTrace$1.run(VerifyStackTrace.java:218)\n" +
+ "6: java.security.AccessController.doPrivileged(Native Method)\n" +
+ "7: VerifyStackTrace.test(VerifyStackTrace.java:227)\n" +
+ "8: VerifyStackTrace.main(VerifyStackTrace.java:182)\n";
+
+ @Override public StackWalker walker() { return walker;}
+ @Override public String description() { return description;}
+ @Override public String expected() { return expected;}
+ }
+ static final class TestCase2 implements TestCase {
+ private final StackWalker walker = StackWalker.getInstance(
+ EnumSet.of(RETAIN_CLASS_REFERENCE, SHOW_REFLECT_FRAMES));
+
+ private final String description = "nStackWalker.getInstance(" +
+ "StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
+ "StackWalker.Option.SHOW_REFLECT_FRAMES)";
+
+ // Note: line numbers and lambda hashes will be erased when
+ // comparing stack traces. However, the stack may change
+ // if some methods are being renamed in the code base.
+ // If the JDK code base changes and the test fails because of that,
+ // then after validating that the actual stack trace obtained
+ // is indeed correct (no frames are skipped that shouldn't)
+ // then you can cut & paste the <-- actual --> stack printed in the
+ // test output in here (don't forget the final \n):
+ private final String expected =
+ "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:211)\n" +
+ "2: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:147)\n" +
+ "3: VerifyStackTrace$Handle.run(VerifyStackTrace.java:160)\n" +
+ "4: VerifyStackTrace.invoke(VerifyStackTrace.java:190)\n" +
+ "5: sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
+ "6: sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" +
+ "7: sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" +
+ "8: java.lang.reflect.Method.invoke(Method.java:520)\n" +
+ "9: VerifyStackTrace$1.run(VerifyStackTrace.java:220)\n" +
+ "10: java.security.AccessController.doPrivileged(Native Method)\n" +
+ "11: VerifyStackTrace.test(VerifyStackTrace.java:229)\n" +
+ "12: VerifyStackTrace.main(VerifyStackTrace.java:185)\n";
+
+ @Override public StackWalker walker() { return walker;}
+ @Override public String description() { return description;}
+ @Override public String expected() { return expected;}
+ }
+ static class TestCase3 implements TestCase {
+ private final StackWalker walker = StackWalker.getInstance(
+ EnumSet.of(RETAIN_CLASS_REFERENCE, SHOW_HIDDEN_FRAMES));
+
+ private final String description = "StackWalker.getInstance(" +
+ "StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
+ "StackWalker.Option.SHOW_HIDDEN_FRAMES)";
+
+ // Note: line numbers and lambda hashes will be erased when
+ // comparing stack traces. However, the stack may change
+ // if some methods are being renamed in the code base.
+ // If the JDK code base changes and the test fails because of that,
+ // then after validating that the actual stack trace obtained
+ // is indeed correct (no frames are skipped that shouldn't)
+ // then you can cut & paste the <-- actual --> stack printed in the
+ // test output in here (don't forget the final \n):
+ private final String expected =
+ "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:213)\n" +
+ "2: VerifyStackTrace$$Lambda$1/662441761.run(Unknown Source)\n" +
+ "3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:149)\n" +
+ "4: java.lang.invoke.LambdaForm$DMH/2008017533.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
+ "5: java.lang.invoke.LambdaForm$MH/1395089624.invoke_MT(LambdaForm$MH)\n" +
+ "6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:162)\n" +
+ "7: VerifyStackTrace.invoke(VerifyStackTrace.java:192)\n" +
+ "8: sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
+ "9: sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n" +
+ "10: sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n" +
+ "11: java.lang.reflect.Method.invoke(Method.java:520)\n" +
+ "12: VerifyStackTrace$1.run(VerifyStackTrace.java:222)\n" +
+ "13: java.security.AccessController.doPrivileged(Native Method)\n" +
+ "14: VerifyStackTrace.test(VerifyStackTrace.java:231)\n" +
+ "15: VerifyStackTrace.main(VerifyStackTrace.java:188)\n";
+
+ @Override public StackWalker walker() { return walker;}
+ @Override public String description() { return description;}
+ @Override public String expected() { return expected;}
+ }
+
+ static final class TestCase4 extends TestCase3 {
+ private final StackWalker walker = StackWalker.getInstance(
+ EnumSet.allOf(StackWalker.Option.class));
+
+ private final String description = "StackWalker.getInstance(" +
+ "StackWalker.Option.RETAIN_CLASS_REFERENCE, " +
+ "StackWalker.Option.SHOW_HIDDEN_FRAMES, " +
+ "StackWalker.Option.SHOW_REFLECT_FRAMES)";
+
+ @Override public StackWalker walker() {return walker;}
+ @Override public String description() {return description;}
+ }
+
+ public static class Handle implements Runnable {
+
+ Runnable impl;
+ public Handle(Runnable run) {
+ this.impl = run;
+ }
+
+ public void execute(Runnable run) {
+ run.run();
+ }
+
+ public void run() {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandle handle = null;
+ try {
+ handle = lookup.findVirtual(Handle.class, "execute",
+ MethodType.methodType(void.class, Runnable.class));
+ } catch(NoSuchMethodException | IllegalAccessException x) {
+ throw new RuntimeException(x);
+ }
+ try {
+ handle.invoke(this, impl);
+ } catch(Error | RuntimeException x) {
+ throw x;
+ } catch(Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+ }
+
+ static String prepare(String produced, boolean eraseSensitiveInfo) {
+ if (eraseSensitiveInfo) {
+ // Erase sensitive information before comparing:
+ // comparing line numbers is too fragile, so we just erase them
+ // out before comparing. We also erase the hash-like names of
+ // synthetic frames introduced by lambdas & method handles
+ return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
+ .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
+ .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
+ .replaceAll("\\$[0-9]+", "\\$??");
+ } else {
+ return produced;
+ }
+ }
+
+
+ public static void main(String[] args) {
+ test(new TestCase1());
+ test(new TestCase2());
+ test(new TestCase3());
+ test(new TestCase4());
+ }
+
+ public static void invoke(Runnable run) {
+ run.run();
+ }
+
+ static final class Recorder {
+ boolean found; // stop recording after main
+ public void recordSTE(long counter, StringBuilder s, StackFrame f) {
+ if (found) return;
+ found = VerifyStackTrace.class.equals(f.getDeclaringClass()) &&
+ "main".equals(f.getMethodName());
+ String line = String.format("%d: %s", counter, f.toStackTraceElement());
+ s.append(line).append('\n');
+ System.out.println(line);
+ }
+ }
+
+
+ static void test(TestCase test) {
+ System.out.println("\nTesting: " + test.description());
+ final AtomicLong counter = new AtomicLong();
+ final StringBuilder builder = new StringBuilder();
+ final Recorder recorder = new Recorder();
+ final Runnable run = () -> test.walker().forEach(
+ f -> recorder.recordSTE(counter.incrementAndGet(), builder, f));
+ final Handle handle = new Handle(run);
+
+ // We're not using lambda on purpose here. We want the anonymous
+ // class on the stack.
+ PrivilegedAction<Object> pa = new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ try {
+ return VerifyStackTrace.class
+ .getMethod("invoke", Runnable.class)
+ .invoke(null, handle);
+ } catch (NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException ex) {
+ System.out.flush();
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ AccessController.doPrivileged(pa);
+ System.out.println("Main found: " + recorder.found);
+ if (!Objects.equals(prepare(test.expected(), true), prepare(builder.toString(), true))) {
+ System.out.flush();
+ try {
+ // sleep to make it less likely that System.out & System.err will
+ // interleave.
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) {
+ }
+ System.err.println("\nUnexpected stack trace: "
+ + "\n<!-- expected -->\n"
+ + prepare(test.expected(), true)
+ + "\n<-- actual -->\n"
+ + prepare(builder.toString(), false));
+ throw new RuntimeException("Unexpected stack trace for: " + test.description());
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/WalkFunction.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8020968
+ * @summary Sanity test for Function wildcard signature
+ * @run main WalkFunction
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+public class WalkFunction {
+ private static final StackWalker walker = StackWalker.getInstance();
+
+ public static void main(String... args) throws Exception {
+ testFunctions();
+ testWildcards();
+ walker.walk(counter());
+ walker.walk(wildCounter());
+ }
+
+ private static void testFunctions() {
+ walker.walk(Stream::count);
+
+ try {
+ walker.walk(null);
+ throw new RuntimeException("NPE expected");
+ } catch (NullPointerException e) {}
+
+ Optional<StackFrame> result = walker.walk(WalkFunction::reduce);
+ if (!result.get().getClassName().equals(WalkFunction.class.getName())) {
+ throw new RuntimeException(result.get() + " expected: " + WalkFunction.class.getName());
+ }
+ }
+
+ static Optional<StackFrame> reduce(Stream<StackFrame> stream) {
+ return stream.reduce((r,f) -> r.getClassName().compareTo(f.getClassName()) > 0 ? f : r);
+ }
+
+ private static void testWildcards() {
+ Function<? super Stream<? extends StackFrame>, Void> f1 = WalkFunction::function;
+ Function<? super Stream<? super StackFrame>, Void> f2 = WalkFunction::function;
+ Function<? super Stream<StackFrame>, Void> f3 = WalkFunction::function;
+ Function<Stream<? extends StackFrame>, Void> f4 = WalkFunction::function;
+ Function<Stream<? super StackFrame>, Void> f5 = WalkFunction::function;
+ Function<Stream<StackFrame>, Void> f6 = WalkFunction::function;
+ walker.walk(f1);
+ walker.walk(f2);
+ walker.walk(f3);
+ walker.walk(f4);
+ walker.walk(f5);
+ walker.walk(f6);
+ }
+
+ private static Void function(Stream<?> s) {
+ return null;
+ }
+
+ private static Function<Stream<?>, Long> wildCounter() {
+ return Stream::count;
+ }
+ private static <T> Function<Stream<T>, Long> counter() {
+ return Stream::count;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/noperms.policy Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,5 @@
+/*
+ * grant nothing
+ */
+grant {};
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/stackwalk.policy Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,4 @@
+grant {
+ permission java.lang.StackFramePermission "retainClassReference";
+};
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/stackwalktest.policy Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,5 @@
+grant {
+ permission java.lang.StackFramePermission "retainClassReference";
+ permission java.util.PropertyPermission "seed", "read";
+};
+
--- a/jdk/test/java/lang/invoke/T8139885.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/lang/invoke/T8139885.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,6 +34,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
import java.util.*;
import static java.lang.invoke.MethodType.methodType;
@@ -413,6 +414,18 @@
}
@Test
+ public static void testAsSpreaderIllegalMethodType() throws Throwable {
+ MethodHandle h = MethodHandles.dropArguments(MethodHandles.constant(String.class, ""), 0, int.class, int.class);
+ boolean caught = false;
+ try {
+ MethodHandle s = h.asSpreader(String[].class, 1);
+ } catch (WrongMethodTypeException wmte) {
+ caught = true;
+ }
+ assertTrue(caught);
+ }
+
+ @Test
public static void testAsCollector() throws Throwable {
MethodHandle collector = SpreadCollect.MH_forCollecting.asCollector(1, int[].class, 1);
assertEquals(SpreadCollect.MT_collector1, collector.type());
--- a/jdk/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/security/KeyStore/PKCS12/api_cert_chain.p12_expected.data Wed Dec 02 09:34:55 2015 -0800
@@ -1,7 +1,7 @@
-MD5: C6:17:CB:93:51:32:DA:C9:CF:0E:24:E3:16:FA:91:6A
SHA1: 09:F1:08:B1:B3:28:22:23:22:F7:5F:6D:4A:8D:0E:0A:5E:6D:56:FB
-MD5: C5:97:13:F6:24:E4:DF:9A:6B:4F:E8:73:90:78:24:95
+SHA256: AD:57:47:67:20:96:49:86:53:E4:10:EF:BD:4D:D2:B0:81:C0:B0:BB:62:AE:BE:47:80:DC:00:F8:E3:E7:66:B5
SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42
-MD5: 0F:8A:2A:DB:D4:A5:CD:A6:9C:EE:DA:47:A0:9D:10:2B
+SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF
SHA1: 7D:48:4D:1C:F8:55:E8:79:6A:B0:19:E1:26:4F:AC:FD:57:6B:38:A0
+SHA256: 0A:14:3F:88:8D:C2:D6:97:3E:02:0F:5F:17:E3:D9:FE:CF:93:10:2C:3C:8D:81:AC:06:2F:32:39:4D:0E:CB:6A
Alias name: servercert
--- a/jdk/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/security/KeyStore/PKCS12/api_private_key.p12_expected.data Wed Dec 02 09:34:55 2015 -0800
@@ -1,3 +1,3 @@
-MD5: 67:10:B1:84:A4:0B:AF:1F:5B:1A:C7:EB:C6:2C:DB:CE
SHA1: 48:22:E2:C2:47:9F:75:E3:52:56:9C:20:37:DF:03:7F:CD:9F:87:38
+SHA256: 9B:DF:B9:EC:DB:3E:EF:BD:61:8F:C3:62:BD:3E:95:FE:E5:B6:A3:F9:94:3D:8D:C1:AE:E9:44:86:25:FA:C1:1B
Alias name: pkcs12testenduser1
--- a/jdk/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/security/KeyStore/PKCS12/api_private_key_not_match.p12_expected.data Wed Dec 02 09:34:55 2015 -0800
@@ -1,3 +1,3 @@
-MD5: C5:97:13:F6:24:E4:DF:9A:6B:4F:E8:73:90:78:24:95
SHA1: 2B:CE:0C:E1:35:B9:9D:FE:5A:6E:25:88:01:F7:E9:E5:7B:89:17:42
+SHA256: 65:F3:0A:64:F2:52:B2:4E:F8:76:C5:D0:6D:53:7C:E8:00:AE:F4:95:3C:CC:CB:01:6B:22:AF:46:36:50:CF:FF
Alias name: pkcs12testenduser1
--- a/jdk/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/security/KeyStore/PKCS12/api_two_pass.p12_expected.data Wed Dec 02 09:34:55 2015 -0800
@@ -1,3 +1,3 @@
-MD5: FE:A8:AA:47:D0:CB:A9:9D:9F:88:DC:4D:55:85:F4:95
SHA1: 77:90:EC:65:C5:0C:FD:F2:1E:B0:3A:BD:43:21:1A:C6:FD:18:8C:AB
+SHA256: 8E:C8:49:82:B8:4B:89:8E:61:2D:CD:F6:D6:34:96:04:91:6F:1B:08:F5:CD:BD:23:ED:94:22:5A:B4:7A:39:DD
Alias name: pkcs12testenduser1
--- a/jdk/test/java/sql/testng/test/sql/StatementTests.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/sql/testng/test/sql/StatementTests.java Wed Dec 02 09:34:55 2015 -0800
@@ -24,6 +24,7 @@
import java.sql.SQLException;
import static org.testng.Assert.assertEquals;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -33,18 +34,29 @@
public class StatementTests extends BaseTest {
protected StubStatement stmt;
+ protected static String maxIdentifier;
@BeforeMethod
public void setUpMethod() throws Exception {
stmt = new StubStatement();
}
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ int maxLen = 128;
+ StringBuilder s = new StringBuilder(maxLen);
+ for (int i = 0; i < maxLen; i++) {
+ s.append('a');
+ }
+ maxIdentifier = s.toString();
+ }
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
+
@Test(dataProvider = "validEnquotedLiteralValues")
- public void test00(String s, String expected) {
+ public void test00(String s, String expected) throws SQLException {
assertEquals(stmt.enquoteLiteral(s), expected);
}
@@ -53,7 +65,7 @@
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
- public void test01() {
+ public void test01() throws SQLException {
stmt.enquoteLiteral(null);
}
@@ -90,6 +102,24 @@
}
/*
+ * Validate that isSimpleIdentifier returns the expected value
+ */
+ @Test(dataProvider = "simpleIdentifierValues")
+ public void test05(String s, boolean expected) throws SQLException {
+ assertEquals(stmt.isSimpleIdentifier(s), expected);
+ }
+
+ /*
+ * Validate a NullPointerException is thrown is the string passed to
+ * isSimpleIdentifier is null
+ */
+ @Test(expectedExceptions = NullPointerException.class)
+ public void test06() throws SQLException {
+ stmt.isSimpleIdentifier(null);
+
+ }
+
+ /*
* DataProvider used to provide strings that will be used to validate
* that enquoteLiteral converts a string to a literal and every instance of
* a single quote will be converted into two single quotes in the literal.
@@ -114,6 +144,10 @@
@DataProvider(name = "validIdentifierValues")
protected Object[][] validEnquotedIdentifierValues() {
return new Object[][]{
+ {"b", false, "b"},
+ {"b", true, "\"b\""},
+ {maxIdentifier, false, maxIdentifier},
+ {maxIdentifier, true, "\"" + maxIdentifier + "\""},
{"Hello", false, "Hello"},
{"Hello", true, "\"Hello\""},
{"G'Day", false, "\"G'Day\""},
@@ -130,16 +164,34 @@
*/
@DataProvider(name = "invalidIdentifierValues")
protected Object[][] invalidEnquotedIdentifierValues() {
- int invalidLen = 129;
- StringBuilder s = new StringBuilder(invalidLen);
- for (int i = 0; i < invalidLen; i++) {
- s.append('a');
- }
return new Object[][]{
{"Hel\"lo", false},
{"\"Hel\"lo\"", true},
{"Hello" + '\0', false},
{"", false},
- {s.toString(), false},};
+ {maxIdentifier + 'a', false},
+ };
}
+
+ /*
+ * DataProvider used to provide strings that will be used to validate
+ * that isSimpleIdentifier returns the correct value based on the
+ * identifier specified.
+ */
+ @DataProvider(name = "simpleIdentifierValues")
+ protected Object[][] simpleIdentifierValues() {
+ return new Object[][]{
+ {"b", true},
+ {"Hello", true},
+ {"\"Gotham\"", false},
+ {"G'Day", false},
+ {"Bruce Wayne", false},
+ {"GoodDay$", false},
+ {"Dick_Grayson", true},
+ {"Batmobile1966", true},
+ {maxIdentifier, true},
+ {maxIdentifier + 'a', false},
+ {"", false},};
+ }
+
}
--- a/jdk/test/java/util/Collections/CheckedMapBash.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Collections/CheckedMapBash.java Wed Dec 02 09:34:55 2015 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4904067 5023830 7129185
+ * @bug 4904067 5023830 7129185 8072015
* @summary Unit test for Collections.checkedMap
* @author Josh Bloch
* @run testng CheckedMapBash
@@ -53,7 +53,7 @@
Object newHead;
do {
newHead = new Integer(rnd.nextInt());
- } while (m.containsKey(newHead));
+ } while (m.containsKey(newHead) || newHead.equals(nil));
m.put(newHead, head);
head = newHead;
}
@@ -99,16 +99,16 @@
}
@Test(dataProvider = "Supplier<Map<Integer,Integer>>")
- public static void testCheckeMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
+ public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
Map m = supplier.get();
for (int i=0; i<mapSize; i++)
if (m.put(new Integer(i), new Integer(2*i)) != null)
- fail("put returns a non-null value erroenously.");
+ fail("put returns a non-null value erroneously.");
for (int i=0; i<2*mapSize; i++)
if (m.containsValue(new Integer(i)) != (i%2==0))
fail("contains value "+i);
if (m.put(nil, nil) == null)
- fail("put returns a null value erroenously.");
+ fail("put returns a null value erroneously.");
Map m2 = supplier.get(); m2.putAll(m);
if (!m.equals(m2))
fail("Clone not equal to original. (1)");
@@ -147,7 +147,7 @@
ArrayList<Object[]> iters = new ArrayList<>(makeCheckedMaps());
iters.ensureCapacity(numItr * iters.size());
for (int each=1; each < numItr; each++) {
- iters.addAll( makeCheckedMaps());
+ iters.addAll(makeCheckedMaps());
}
return iters.iterator();
}
@@ -158,19 +158,20 @@
}
public static Collection<Object[]> makeCheckedMaps() {
- return Arrays.asList(
- new Object[]{"Collections.checkedMap(HashMap)",
- (Supplier) () -> {return Collections.checkedMap(new HashMap(), Integer.class, Integer.class);}},
- new Object[]{"Collections.checkedMap(TreeSet(reverseOrder)",
- (Supplier) () -> {return Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}},
- new Object[]{"Collections.checkedMap(TreeSet).descendingSet()",
- (Supplier) () -> {return Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}},
- new Object[]{"Collections.checkedNavigableMap(TreeSet)",
- (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class);}},
- new Object[]{"Collections.checkedNavigableMap(TreeSet(reverseOrder)",
- (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class);}},
- new Object[]{"Collections.checkedNavigableMap().descendingSet()",
- (Supplier) () -> {return Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class);}}
- );
+ Object[][] params = {
+ {"Collections.checkedMap(HashMap)",
+ (Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)},
+ {"Collections.checkedMap(TreeMap(reverseOrder))",
+ (Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+ {"Collections.checkedMap(TreeMap.descendingMap())",
+ (Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap)",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap(reverseOrder))",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+ {"Collections.checkedNavigableMap(TreeMap.descendingMap())",
+ (Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+ };
+ return Arrays.asList(params);
}
}
--- a/jdk/test/java/util/Collections/CheckedSetBash.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Collections/CheckedSetBash.java Wed Dec 02 09:34:55 2015 -0800
@@ -146,25 +146,26 @@
ArrayList<Object[]> iters = new ArrayList<>(makeCheckedSets());
iters.ensureCapacity(numItr * iters.size());
for (int each=1; each < numItr; each++) {
- iters.addAll( makeCheckedSets());
+ iters.addAll(makeCheckedSets());
}
return iters.iterator();
}
public static Collection<Object[]> makeCheckedSets() {
- return Arrays.asList(
- new Object[]{"Collections.checkedSet(HashSet)",
- (Supplier) () -> {return Collections.checkedSet(new HashSet(), Integer.class);}},
- new Object[]{"Collections.checkedSet(TreeSet(reverseOrder)",
- (Supplier) () -> {return Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class);}},
- new Object[]{"Collections.checkedSet(TreeSet).descendingSet()",
- (Supplier) () -> {return Collections.checkedSet(new TreeSet().descendingSet(), Integer.class);}},
- new Object[]{"Collections.checkedNavigableSet(TreeSet)",
- (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(), Integer.class);}},
- new Object[]{"Collections.checkedNavigableSet(TreeSet(reverseOrder)",
- (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class);}},
- new Object[]{"Collections.checkedNavigableSet().descendingSet()",
- (Supplier) () -> {return Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class);}}
- );
+ Object[][] params = {
+ {"Collections.checkedSet(HashSet)",
+ (Supplier) () -> Collections.checkedSet(new HashSet(), Integer.class)},
+ {"Collections.checkedSet(TreeSet(reverseOrder))",
+ (Supplier) () -> Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+ {"Collections.checkedSet(TreeSet.descendingSet())",
+ (Supplier) () -> Collections.checkedSet(new TreeSet().descendingSet(), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet)",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet(reverseOrder))",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+ {"Collections.checkedNavigableSet(TreeSet.descendingSet())",
+ (Supplier) () -> Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class)},
+ };
+ return Arrays.asList(params);
}
}
--- a/jdk/test/java/util/Collections/EmptyCollectionSerialization.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Collections/EmptyCollectionSerialization.java Wed Dec 02 09:34:55 2015 -0800
@@ -58,7 +58,7 @@
Object singleton = o.get();
assertSame(o.get(), singleton, description + ": broken Supplier not returning singleton");
Object copy = patheticDeepCopy(singleton);
- assertSame( copy, singleton, description + ": " +
+ assertSame(copy, singleton, description + ": " +
copy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(copy)) +
" is not the singleton " +
singleton.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(singleton)));
@@ -73,27 +73,28 @@
}
public static Collection<Object[]> makeSingletons() {
- return Arrays.asList(
- new Object[]{"Collections.EMPTY_LIST",
- (Supplier) () -> {return Collections.EMPTY_LIST;}},
- new Object[]{"Collections.EMPTY_MAP",
- (Supplier) () -> {return Collections.EMPTY_MAP;}},
- new Object[]{"Collections.EMPTY_SET",
- (Supplier) () -> {return Collections.EMPTY_SET;}},
- new Object[]{"Collections.singletonMap()",
- (Supplier) () -> {return Collections.emptyList();}},
- new Object[]{"Collections.emptyMap()",
- (Supplier) () -> {return Collections.emptyMap();}},
- new Object[]{"Collections.emptySet()",
- (Supplier) () -> {return Collections.emptySet();}},
- new Object[]{"Collections.emptySortedSet()",
- (Supplier) () -> {return Collections.emptySortedSet();}},
- new Object[]{"Collections.emptySortedMap()",
- (Supplier) () -> {return Collections.emptySortedMap();}},
- new Object[]{"Collections.emptyNavigableSet()",
- (Supplier) () -> {return Collections.emptyNavigableSet();}},
- new Object[]{"Collections.emptyNavigableMap()",
- (Supplier) () -> {return Collections.emptyNavigableMap();}}
- );
+ Object[][] params = {
+ {"Collections.EMPTY_LIST",
+ (Supplier) () -> Collections.EMPTY_LIST},
+ {"Collections.EMPTY_MAP",
+ (Supplier) () -> Collections.EMPTY_MAP},
+ {"Collections.EMPTY_SET",
+ (Supplier) () -> Collections.EMPTY_SET},
+ {"Collections.emptyList()",
+ (Supplier) () -> Collections.emptyList()},
+ {"Collections.emptyMap()",
+ (Supplier) () -> Collections.emptyMap()},
+ {"Collections.emptySet()",
+ (Supplier) () -> Collections.emptySet()},
+ {"Collections.emptySortedSet()",
+ (Supplier) () -> Collections.emptySortedSet()},
+ {"Collections.emptySortedMap()",
+ (Supplier) () -> Collections.emptySortedMap()},
+ {"Collections.emptyNavigableSet()",
+ (Supplier) () -> Collections.emptyNavigableSet()},
+ {"Collections.emptyNavigableMap()",
+ (Supplier) () -> Collections.emptyNavigableMap()},
+ };
+ return Arrays.asList(params);
}
}
--- a/jdk/test/java/util/Locale/LocaleEnhanceTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Locale/LocaleEnhanceTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -1180,8 +1180,11 @@
dataDir = new File(dataDirName);
}
- if (dataDir == null || !dataDir.isDirectory()) {
- errln("Could not locate the serialized test case data location");
+ if (dataDir == null) {
+ errln("'dataDir' is null. serialized.data.dir Property value is "+dataDirName);
+ return;
+ } else if (!dataDir.isDirectory()) {
+ errln("'dataDir' is not a directory. dataDir: "+dataDir.toString());
return;
}
--- a/jdk/test/java/util/ResourceBundle/Test4300693.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/ResourceBundle/Test4300693.java Wed Dec 02 09:34:55 2015 -0800
@@ -22,7 +22,6 @@
*/
/*
@test
- @ignore 6876961
@summary test that ResourceBundle.getBundle can be called recursively
@build Test4300693RB
@run main Test4300693
--- a/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -202,9 +202,9 @@
db.addCollection(PriorityQueue::new);
- // ArrayDeque fails some tests since it's fail-fast support is weaker
+ // ArrayDeque fails some tests since its fail-fast support is weaker
// than other collections and limited to detecting most, but not all,
- // removals. It probably requires it's own test since it is difficult
+ // removals. It probably requires its own test since it is difficult
// to abstract out the conditions under which it fails-fast.
// db.addCollection(ArrayDeque::new);
--- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -85,7 +85,7 @@
@Test
public class SpliteratorTraversingAndSplittingTest {
- private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
+ private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 42);
private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE});
private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE});
--- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,150 +34,148 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=7000 CancelledProducerConsumerLoops
* @summary Checks for responsiveness of blocking queues to cancellation.
- * Runs under the assumption that ITERS computations require more than
- * TIMEOUT msecs to complete.
*/
-import java.util.concurrent.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SplittableRandom;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
public class CancelledProducerConsumerLoops {
- static final int CAPACITY = 100;
- static final long TIMEOUT = 100;
-
- static final ExecutorService pool = Executors.newCachedThreadPool();
- static boolean print = false;
+ static ExecutorService pool;
public static void main(String[] args) throws Exception {
- int maxPairs = 8;
- int iters = 1000000;
+ final int maxPairs = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
- if (args.length > 0)
- maxPairs = Integer.parseInt(args[0]);
-
- print = true;
-
+ pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) {
- System.out.println("Pairs:" + i);
- try {
- oneTest(i, iters);
- }
- catch (BrokenBarrierException bb) {
- // OK, ignore
- }
- Thread.sleep(100);
+ final List<BlockingQueue<Integer>> queues = new ArrayList<>();
+ queues.add(new ArrayBlockingQueue<Integer>(100));
+ queues.add(new LinkedBlockingQueue<Integer>(100));
+ queues.add(new LinkedBlockingDeque<Integer>(100));
+ queues.add(new SynchronousQueue<Integer>());
+ // unbounded queue implementations are prone to OOME:
+ // PriorityBlockingQueue, LinkedTransferQueue
+ for (BlockingQueue<Integer> queue : queues)
+ new CancelledProducerConsumerLoops(i, queue).run();
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
- throw new Error();
- }
+ if (! pool.awaitTermination(10L, TimeUnit.SECONDS))
+ throw new AssertionError("timed out");
+ pool = null;
+ }
- static void oneRun(BlockingQueue<Integer> q, int npairs, int iters) throws Exception {
- if (print)
- System.out.printf("%-18s", q.getClass().getSimpleName());
- LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
- CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer);
+ final int npairs;
+ final BlockingQueue<Integer> queue;
+ final CountDownLatch producersInterrupted;
+ final CountDownLatch consumersInterrupted;
+ final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
+ final CyclicBarrier barrier;
+ final SplittableRandom rnd = new SplittableRandom();
+ volatile boolean done = false;
+
+ CancelledProducerConsumerLoops(int npairs, BlockingQueue<Integer> queue) {
+ this.npairs = npairs;
+ this.queue = queue;
+ this.producersInterrupted = new CountDownLatch(npairs - 1);
+ this.consumersInterrupted = new CountDownLatch(npairs - 1);
+ this.barrier = new CyclicBarrier(npairs * 2 + 1, timer);
+ }
+
+ void run() throws Exception {
Future<?>[] prods = new Future<?>[npairs];
Future<?>[] cons = new Future<?>[npairs];
- for (int i = 0; i < npairs; ++i) {
- prods[i] = pool.submit(new Producer(q, barrier, iters));
- cons[i] = pool.submit(new Consumer(q, barrier, iters));
+ for (int i = 0; i < npairs; i++) {
+ prods[i] = pool.submit(new Producer());
+ cons[i] = pool.submit(new Consumer());
}
barrier.await();
- Thread.sleep(TIMEOUT);
- boolean tooLate = false;
+ Thread.sleep(rnd.nextInt(5));
- for (int i = 1; i < npairs; ++i) {
- if (!prods[i].cancel(true))
- tooLate = true;
- if (!cons[i].cancel(true))
- tooLate = true;
+ for (int i = 1; i < npairs; i++) {
+ if (!prods[i].cancel(true) ||
+ !cons[i].cancel(true))
+ throw new AssertionError("completed before done");
+ }
+
+ for (int i = 1; i < npairs; i++) {
+ assertCancelled(prods[i]);
+ assertCancelled(cons[i]);
}
- Object p0 = prods[0].get();
- Object c0 = cons[0].get();
+ if (!producersInterrupted.await(10L, TimeUnit.SECONDS))
+ throw new AssertionError("timed out");
+ if (!consumersInterrupted.await(10L, TimeUnit.SECONDS))
+ throw new AssertionError("timed out");
+ if (prods[0].isDone() || prods[0].isCancelled())
+ throw new AssertionError("completed too early");
+
+ done = true;
+
+ if (! (prods[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
+ throw new AssertionError("expected Integer");
+ if (! (cons[0].get(10L, TimeUnit.SECONDS) instanceof Integer))
+ throw new AssertionError("expected Integer");
+ }
- if (!tooLate) {
- for (int i = 1; i < npairs; ++i) {
- if (!prods[i].isDone() || !prods[i].isCancelled())
- throw new Error("Only one producer thread should complete");
- if (!cons[i].isDone() || !cons[i].isCancelled())
- throw new Error("Only one consumer thread should complete");
+ void assertCancelled(Future<?> future) throws Exception {
+ if (!future.isDone())
+ throw new AssertionError("not done");
+ if (!future.isCancelled())
+ throw new AssertionError("not cancelled");
+ try {
+ future.get(10L, TimeUnit.SECONDS);
+ throw new AssertionError("should throw CancellationException");
+ } catch (CancellationException success) {}
+ }
+
+ class Producer implements Callable<Integer> {
+ public Integer call() throws Exception {
+ barrier.await();
+ int sum = 0;
+ try {
+ int x = 4321;
+ while (!done) {
+ if (Thread.interrupted()) throw new InterruptedException();
+ x = LoopHelpers.compute1(x);
+ sum += LoopHelpers.compute2(x);
+ queue.offer(new Integer(x), 1, TimeUnit.MILLISECONDS);
+ }
+ } catch (InterruptedException cancelled) {
+ producersInterrupted.countDown();
}
- }
- else
- System.out.print("(cancelled too late) ");
-
- long endTime = System.nanoTime();
- long time = endTime - timer.startTime;
- if (print) {
- double secs = (double)(time) / 1000000000.0;
- System.out.println("\t " + secs + "s run time");
+ return sum;
}
}
- static void oneTest(int pairs, int iters) throws Exception {
-
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
- oneRun(new SynchronousQueue<Integer>(), pairs, iters / 8);
-
- /* unbounded queue implementations are prone to OOME
- oneRun(new PriorityBlockingQueue<Integer>(iters / 2 * pairs), pairs, iters / 4);
- oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
- */
- }
-
- abstract static class Stage implements Callable<Integer> {
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- final int iters;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
- }
- }
-
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
+ class Consumer implements Callable<Integer> {
public Integer call() throws Exception {
barrier.await();
- int s = 0;
- int l = 4321;
- for (int i = 0; i < iters; ++i) {
- l = LoopHelpers.compute1(l);
- s += LoopHelpers.compute2(l);
- if (!queue.offer(new Integer(l), 1, TimeUnit.SECONDS))
- break;
+ int sum = 0;
+ try {
+ while (!done) {
+ Integer x = queue.poll(1, TimeUnit.MILLISECONDS);
+ if (x != null)
+ sum += LoopHelpers.compute1(x.intValue());
+ }
+ } catch (InterruptedException cancelled) {
+ consumersInterrupted.countDown();
}
- return new Integer(s);
- }
- }
-
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- public Integer call() throws Exception {
- barrier.await();
- int l = 0;
- int s = 0;
- for (int i = 0; i < iters; ++i) {
- Integer x = queue.poll(1, TimeUnit.SECONDS);
- if (x == null)
- break;
- l = LoopHelpers.compute1(x.intValue());
- s += l;
- }
- return new Integer(s);
+ return sum;
}
}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/DrainToFails.java Wed Dec 02 09:34:55 2015 -0800
@@ -37,8 +37,19 @@
* @summary Test drainTo failing due to c.add throwing
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
@SuppressWarnings({"unchecked", "rawtypes"})
public class DrainToFails {
--- a/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/Interrupt.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,9 +28,19 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
public class Interrupt {
@@ -61,7 +71,7 @@
checkInterrupted0(fs, immediateExecutor);
checkInterrupted0(fs, delayedExecutor);
stpe.shutdown();
- check(stpe.awaitTermination(10, SECONDS));
+ check(stpe.awaitTermination(10L, SECONDS));
}
static void testQueue(final BlockingQueue<Object> q) {
--- a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,13 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Iterator;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
public class LastElement {
void test(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -74,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,151 +34,124 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=3600 MultipleProducersSingleConsumerLoops
* @summary multiple producers and single consumer using blocking queues
*/
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.atomic.AtomicInteger;
public class MultipleProducersSingleConsumerLoops {
- static final int CAPACITY = 100;
- static final ExecutorService pool = Executors.newCachedThreadPool();
- static boolean print = false;
- static int producerSum;
- static int consumerSum;
-
- static synchronized void addProducerSum(int x) {
- producerSum += x;
- }
-
- static synchronized void addConsumerSum(int x) {
- consumerSum += x;
- }
-
- static synchronized void checkSum() {
- if (producerSum != consumerSum)
- throw new Error("CheckSum mismatch");
- }
+ static ExecutorService pool;
public static void main(String[] args) throws Exception {
- int maxProducers = 5;
- int iters = 100000;
-
- if (args.length > 0)
- maxProducers = Integer.parseInt(args[0]);
+ final int maxProducers = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
- print = false;
- System.out.println("Warmup...");
- oneTest(1, 10000);
- Thread.sleep(100);
- oneTest(2, 10000);
- Thread.sleep(100);
- print = true;
+ pool = Executors.newCachedThreadPool();
+ for (int i = 1; i <= maxProducers; i += (i+1) >>> 1) {
+ // Adjust iterations to limit typical single runs to <= 10 ms;
+ // Notably, fair queues get fewer iters.
+ // Unbounded queues can legitimately OOME if iterations
+ // high enough, but we have a sufficiently low limit here.
+ run(new ArrayBlockingQueue<Integer>(100), i, 300);
+ run(new LinkedBlockingQueue<Integer>(100), i, 700);
+ run(new LinkedBlockingDeque<Integer>(100), i , 500);
+ run(new LinkedTransferQueue<Integer>(), i, 1000);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 500);
+ run(new SynchronousQueue<Integer>(true), i, 200);
+ run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
+ }
- for (int i = 1; i <= maxProducers; i += (i+1) >>> 1) {
- System.out.println("----------------------------------------");
- System.out.println("Producers:" + i);
- oneTest(i, iters);
- Thread.sleep(100);
- }
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(10L, SECONDS))
throw new Error();
- }
-
- static void oneTest(int producers, int iters) throws Exception {
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), producers, iters);
- oneRun(new LinkedTransferQueue<Integer>(), producers, iters);
+ pool = null;
+ }
- // Don't run PBQ since can legitimately run out of memory
- // if (print)
- // System.out.print("PriorityBlockingQueue ");
- // oneRun(new PriorityBlockingQueue<Integer>(), producers, iters);
-
- oneRun(new SynchronousQueue<Integer>(), producers, iters);
- if (print)
- System.out.println("fair implementations:");
- oneRun(new SynchronousQueue<Integer>(true), producers, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), producers, iters);
+ static void run(BlockingQueue<Integer> queue, int nproducers, int iters) throws Exception {
+ new MultipleProducersSingleConsumerLoops(queue, nproducers, iters).run();
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
- }
+ final BlockingQueue<Integer> queue;
+ final int nproducers;
+ final int iters;
+ final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
+ final CyclicBarrier barrier;
+ final AtomicInteger checksum = new AtomicInteger(0);
+ Throwable fail;
+
+ MultipleProducersSingleConsumerLoops(BlockingQueue<Integer> queue, int nproducers, int iters) {
+ this.queue = queue;
+ this.nproducers = nproducers;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(nproducers + 2, timer);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
+ void run() throws Exception {
+ for (int i = 0; i < nproducers; i++)
+ pool.execute(new Producer());
+ pool.execute(new Consumer());
+ barrier.await();
+ barrier.await();
+ System.out.printf("%s, nproducers=%d: %d ms%n",
+ queue.getClass().getSimpleName(), nproducers,
+ NANOSECONDS.toMillis(timer.getTime()));
+ if (checksum.get() != 0) throw new AssertionError("checksum mismatch");
+ if (fail != null) throw new AssertionError(fail);
+ }
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final void run() {
try {
- barrier.await();
- int s = 0;
- int l = hashCode();
- for (int i = 0; i < iters; ++i) {
- l = LoopHelpers.compute1(l);
- l = LoopHelpers.compute2(l);
- queue.put(new Integer(l));
- s += l;
- }
- addProducerSum(s);
- barrier.await();
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ class Producer extends CheckedRunnable {
+ void realRun() throws Throwable {
+ barrier.await();
+ int s = 0;
+ int l = hashCode();
+ for (int i = 0; i < iters; i++) {
+ l = LoopHelpers.compute1(l);
+ l = LoopHelpers.compute2(l);
+ queue.put(new Integer(l));
+ s += l;
+ }
+ checksum.getAndAdd(s);
+ barrier.await();
}
-
- public void run() {
- try {
- barrier.await();
- int s = 0;
- for (int i = 0; i < iters; ++i) {
- s += queue.take().intValue();
- }
- addConsumerSum(s);
- barrier.await();
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
- }
- }
-
}
- static void oneRun(BlockingQueue<Integer> q, int nproducers, int iters) throws Exception {
- if (print)
- System.out.printf("%-18s", q.getClass().getSimpleName());
- LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
- CyclicBarrier barrier = new CyclicBarrier(nproducers + 2, timer);
- for (int i = 0; i < nproducers; ++i) {
- pool.execute(new Producer(q, barrier, iters));
+ class Consumer extends CheckedRunnable {
+ void realRun() throws Throwable {
+ barrier.await();
+ int s = 0;
+ for (int i = 0; i < nproducers * iters; i++) {
+ s += queue.take().intValue();
+ }
+ checksum.getAndAdd(-s);
+ barrier.await();
}
- pool.execute(new Consumer(q, barrier, iters * nproducers));
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- checkSum();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nproducers)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,13 +34,20 @@
/*
* @test
* @bug 6805775 6815766
- * @run main OfferDrainToLoops 300
+ * @run main OfferDrainToLoops 100
* @summary Test concurrent offer vs. drainTo
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SplittableRandom;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.atomic.AtomicLong;
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class OfferDrainToLoops {
@@ -66,22 +73,22 @@
test(new LinkedTransferQueue());
}
- Random getRandom() {
- return ThreadLocalRandom.current();
- }
-
void test(final BlockingQueue q) throws Throwable {
System.out.println(q.getClass().getSimpleName());
final long testDurationNanos = testDurationMillis * 1000L * 1000L;
final long quittingTimeNanos = System.nanoTime() + testDurationNanos;
final long timeoutMillis = 10L * 1000L;
+ final SplittableRandom rnd = new SplittableRandom();
/** Poor man's bounded buffer. */
final AtomicLong approximateCount = new AtomicLong(0L);
abstract class CheckedThread extends Thread {
- CheckedThread(String name) {
+ final SplittableRandom rnd;
+
+ CheckedThread(String name, SplittableRandom rnd) {
super(name);
+ this.rnd = rnd;
setDaemon(true);
start();
}
@@ -99,7 +106,7 @@
}
}
- Thread offerer = new CheckedThread("offerer") {
+ Thread offerer = new CheckedThread("offerer", rnd.split()) {
protected void realRun() {
long c = 0;
for (long i = 0; ! quittingTime(i); i++) {
@@ -113,9 +120,8 @@
Thread.yield();
}}}};
- Thread drainer = new CheckedThread("drainer") {
+ Thread drainer = new CheckedThread("drainer", rnd.split()) {
protected void realRun() {
- final Random rnd = getRandom();
while (! quittingTime()) {
List list = new ArrayList();
int n = rnd.nextBoolean() ?
@@ -131,9 +137,8 @@
approximateCount.set(0); // Releases waiting offerer thread
}};
- Thread scanner = new CheckedThread("scanner") {
+ Thread scanner = new CheckedThread("scanner", rnd.split()) {
protected void realRun() {
- final Random rnd = getRandom();
while (! quittingTime()) {
switch (rnd.nextInt(3)) {
case 0: checkNotContainsNull(q); break;
@@ -157,8 +162,6 @@
failed++;
for (StackTraceElement e : thread.getStackTrace())
System.err.println(e);
- // Kludge alert
- thread.stop();
thread.join(timeoutMillis);
}
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Wed Dec 02 09:34:55 2015 -0800
@@ -40,7 +40,12 @@
* number of aborted timed waits occur without a signal.
*/
-import java.util.concurrent.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
public class PollMemoryLeak {
public static void main(String[] args) throws InterruptedException {
--- a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,149 +34,126 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=3600 ProducerConsumerLoops
* @summary multiple producers and consumers using blocking queues
*/
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.atomic.AtomicInteger;
public class ProducerConsumerLoops {
- static final int CAPACITY = 100;
-
- static final ExecutorService pool = Executors.newCachedThreadPool();
- static boolean print = false;
- static int producerSum;
- static int consumerSum;
- static synchronized void addProducerSum(int x) {
- producerSum += x;
- }
-
- static synchronized void addConsumerSum(int x) {
- consumerSum += x;
- }
-
- static synchronized void checkSum() {
- if (producerSum != consumerSum)
- throw new Error("CheckSum mismatch");
- }
+ static ExecutorService pool;
public static void main(String[] args) throws Exception {
- int maxPairs = 8;
+ final int maxPairs = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
int iters = 10000;
- if (args.length > 0)
- maxPairs = Integer.parseInt(args[0]);
-
- print = false;
- System.out.println("Warmup...");
- oneTest(1, 10000);
- Thread.sleep(100);
- oneTest(2, 10000);
- Thread.sleep(100);
- print = true;
-
+ pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxPairs; i += (i+1) >>> 1) {
- System.out.println("----------------------------------------");
- System.out.println("Pairs: " + i);
- oneTest(i, iters);
- Thread.sleep(100);
+ // Adjust iterations to limit typical single runs to <= 10 ms;
+ // Notably, fair queues get fewer iters.
+ // Unbounded queues can legitimately OOME if iterations
+ // high enough, but we have a sufficiently low limit here.
+ run(new ArrayBlockingQueue<Integer>(100), i, 500);
+ run(new LinkedBlockingQueue<Integer>(100), i, 1000);
+ run(new LinkedBlockingDeque<Integer>(100), i, 1000);
+ run(new LinkedTransferQueue<Integer>(), i, 1000);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 400);
+ run(new SynchronousQueue<Integer>(true), i, 300);
+ run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
+ pool = null;
}
- static void oneTest(int pairs, int iters) throws Exception {
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), pairs, iters);
- oneRun(new LinkedTransferQueue<Integer>(), pairs, iters);
- oneRun(new PriorityBlockingQueue<Integer>(), pairs, iters);
- oneRun(new SynchronousQueue<Integer>(), pairs, iters);
+ static void run(BlockingQueue<Integer> queue, int pairs, int iters) throws Exception {
+ new ProducerConsumerLoops(queue, pairs, iters).run();
+ }
- if (print)
- System.out.println("fair implementations:");
+ final BlockingQueue<Integer> queue;
+ final int pairs;
+ final int iters;
+ final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
+ final CyclicBarrier barrier;
+ final AtomicInteger checksum = new AtomicInteger(0);
+ Throwable fail;
- oneRun(new SynchronousQueue<Integer>(true), pairs, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), pairs, iters);
+ ProducerConsumerLoops(BlockingQueue<Integer> queue, int pairs, int iters) {
+ this.queue = queue;
+ this.pairs = pairs;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(2 * pairs + 1, timer);
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
+ void run() throws Exception {
+ for (int i = 0; i < pairs; i++) {
+ pool.execute(new Producer());
+ pool.execute(new Consumer());
}
+ barrier.await();
+ barrier.await();
+ System.out.printf("%s, pairs=%d: %d ms%n",
+ queue.getClass().getSimpleName(), pairs,
+ NANOSECONDS.toMillis(timer.getTime()));
+ if (checksum.get() != 0) throw new AssertionError("checksum mismatch");
+ if (fail != null) throw new AssertionError(fail);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final void run() {
try {
- barrier.await();
- int s = 0;
- int l = hashCode();
- for (int i = 0; i < iters; ++i) {
- l = LoopHelpers.compute2(l);
- queue.put(new Integer(l));
- s += LoopHelpers.compute1(l);
- }
- addProducerSum(s);
- barrier.await();
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ class Producer extends CheckedRunnable {
+ void realRun() throws Throwable {
+ barrier.await();
+ int s = 0;
+ int l = hashCode();
+ for (int i = 0; i < iters; i++) {
+ l = LoopHelpers.compute2(l);
+ queue.put(new Integer(l));
+ s += LoopHelpers.compute1(l);
+ }
+ checksum.getAndAdd(s);
+ barrier.await();
}
-
- public void run() {
- try {
- barrier.await();
- int l = 0;
- int s = 0;
- for (int i = 0; i < iters; ++i) {
- l = LoopHelpers.compute1(queue.take().intValue());
- s += l;
- }
- addConsumerSum(s);
- barrier.await();
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
- }
- }
-
}
- static void oneRun(BlockingQueue<Integer> q, int npairs, int iters) throws Exception {
- if (print)
- System.out.printf("%-18s", q.getClass().getSimpleName());
- LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
- CyclicBarrier barrier = new CyclicBarrier(npairs * 2 + 1, timer);
- for (int i = 0; i < npairs; ++i) {
- pool.execute(new Producer(q, barrier, iters));
- pool.execute(new Consumer(q, barrier, iters));
+ class Consumer extends CheckedRunnable {
+ void realRun() throws Throwable {
+ barrier.await();
+ int l = 0;
+ int s = 0;
+ for (int i = 0; i < iters; i++) {
+ l = LoopHelpers.compute1(queue.take().intValue());
+ s += l;
+ }
+ checksum.getAndAdd(-s);
+ barrier.await();
}
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- checkSum();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * npairs)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,135 +34,126 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=600 SingleProducerMultipleConsumerLoops
* @summary check ordering for blocking queues with 1 producer and multiple consumers
*/
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
public class SingleProducerMultipleConsumerLoops {
- static final int CAPACITY = 100;
-
- static final ExecutorService pool = Executors.newCachedThreadPool();
- static boolean print = false;
+ static ExecutorService pool;
public static void main(String[] args) throws Exception {
- int maxConsumers = 5;
- int iters = 10000;
-
- if (args.length > 0)
- maxConsumers = Integer.parseInt(args[0]);
+ final int maxConsumers = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
- print = false;
- System.out.println("Warmup...");
- oneTest(1, 10000);
- Thread.sleep(100);
- oneTest(2, 10000);
- Thread.sleep(100);
- print = true;
-
+ pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxConsumers; i += (i+1) >>> 1) {
- System.out.println("----------------------------------------");
- System.out.println("Consumers: " + i);
- oneTest(i, iters);
- Thread.sleep(100);
+ // Adjust iterations to limit typical single runs to <= 10 ms;
+ // Notably, fair queues get fewer iters.
+ // Unbounded queues can legitimately OOME if iterations
+ // high enough, but we have a sufficiently low limit here.
+ run(new ArrayBlockingQueue<Integer>(100), i, 1000);
+ run(new LinkedBlockingQueue<Integer>(100), i, 1000);
+ run(new LinkedBlockingDeque<Integer>(100), i, 1000);
+ run(new LinkedTransferQueue<Integer>(), i, 700);
+ run(new PriorityBlockingQueue<Integer>(), i, 1000);
+ run(new SynchronousQueue<Integer>(), i, 300);
+ run(new SynchronousQueue<Integer>(true), i, 200);
+ run(new ArrayBlockingQueue<Integer>(100, true), i, 100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
+ pool = null;
}
- static void oneTest(int consumers, int iters) throws Exception {
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedBlockingQueue<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedBlockingDeque<Integer>(CAPACITY), consumers, iters);
- oneRun(new LinkedTransferQueue<Integer>(), consumers, iters);
- oneRun(new PriorityBlockingQueue<Integer>(), consumers, iters);
- oneRun(new SynchronousQueue<Integer>(), consumers, iters);
- if (print)
- System.out.println("fair implementations:");
- oneRun(new SynchronousQueue<Integer>(true), consumers, iters);
- oneRun(new ArrayBlockingQueue<Integer>(CAPACITY, true), consumers, iters);
+ static void run(BlockingQueue<Integer> queue, int consumers, int iters) throws Exception {
+ new SingleProducerMultipleConsumerLoops(queue, consumers, iters).run();
+ }
+
+ final BlockingQueue<Integer> queue;
+ final int consumers;
+ final int iters;
+ final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
+ final CyclicBarrier barrier;
+ Throwable fail;
+
+ SingleProducerMultipleConsumerLoops(BlockingQueue<Integer> queue, int consumers, int iters) {
+ this.queue = queue;
+ this.consumers = consumers;
+ this.iters = iters;
+ this.barrier = new CyclicBarrier(consumers + 2, timer);
}
- abstract static class Stage implements Runnable {
- final int iters;
- final BlockingQueue<Integer> queue;
- final CyclicBarrier barrier;
- volatile int result;
- Stage(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- queue = q;
- barrier = b;
- this.iters = iters;
+ void run() throws Exception {
+ pool.execute(new Producer());
+ for (int i = 0; i < consumers; i++) {
+ pool.execute(new Consumer());
}
+ barrier.await();
+ barrier.await();
+ System.out.printf("%s, consumers=%d: %d ms%n",
+ queue.getClass().getSimpleName(), consumers,
+ NANOSECONDS.toMillis(timer.getTime()));
+ if (fail != null) throw new AssertionError(fail);
}
- static class Producer extends Stage {
- Producer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
- }
-
- public void run() {
+ abstract class CheckedRunnable implements Runnable {
+ abstract void realRun() throws Throwable;
+ public final void run() {
try {
- barrier.await();
- for (int i = 0; i < iters; ++i) {
- queue.put(new Integer(i));
- }
- barrier.await();
- result = 432;
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
+ realRun();
+ } catch (Throwable t) {
+ fail = t;
+ t.printStackTrace();
+ throw new AssertionError(t);
}
}
}
- static class Consumer extends Stage {
- Consumer(BlockingQueue<Integer> q, CyclicBarrier b, int iters) {
- super(q, b, iters);
+ class Producer extends CheckedRunnable {
+ volatile int result;
+ void realRun() throws Throwable {
+ barrier.await();
+ for (int i = 0; i < iters * consumers; i++) {
+ queue.put(new Integer(i));
+ }
+ barrier.await();
+ result = 432;
}
-
- public void run() {
- try {
- barrier.await();
- int l = 0;
- int s = 0;
- int last = -1;
- for (int i = 0; i < iters; ++i) {
- Integer item = queue.take();
- int v = item.intValue();
- if (v < last)
- throw new Error("Out-of-Order transfer");
- last = v;
- l = LoopHelpers.compute1(v);
- s += l;
- }
- barrier.await();
- result = s;
- }
- catch (Exception ie) {
- ie.printStackTrace();
- return;
- }
- }
-
}
- static void oneRun(BlockingQueue<Integer> q, int nconsumers, int iters) throws Exception {
- if (print)
- System.out.printf("%-18s", q.getClass().getSimpleName());
- LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
- CyclicBarrier barrier = new CyclicBarrier(nconsumers + 2, timer);
- pool.execute(new Producer(q, barrier, iters * nconsumers));
- for (int i = 0; i < nconsumers; ++i) {
- pool.execute(new Consumer(q, barrier, iters));
+ class Consumer extends CheckedRunnable {
+ volatile int result;
+ void realRun() throws Throwable {
+ barrier.await();
+ int l = 0;
+ int s = 0;
+ int last = -1;
+ for (int i = 0; i < iters; i++) {
+ Integer item = queue.take();
+ int v = item.intValue();
+ if (v < last)
+ throw new Error("Out-of-Order transfer");
+ last = v;
+ l = LoopHelpers.compute1(v);
+ s += l;
+ }
+ barrier.await();
+ result = s;
}
- barrier.await();
- barrier.await();
- long time = timer.getTime();
- if (print)
- System.out.println("\t: " + LoopHelpers.rightJustify(time / (iters * nconsumers)) + " ns per transfer");
}
-
}
--- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -40,17 +40,19 @@
* @author Chris Hegarty
*/
+import static java.util.concurrent.CompletableFuture.runAsync;
+import static java.util.concurrent.CompletableFuture.supplyAsync;
+import static java.util.concurrent.ForkJoinPool.commonPool;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import java.lang.reflect.Array;
import java.util.concurrent.Phaser;
-import static java.util.concurrent.TimeUnit.*;
import java.util.concurrent.CompletableFuture;
-import static java.util.concurrent.CompletableFuture.*;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import static java.util.concurrent.ForkJoinPool.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Basic {
@@ -112,7 +114,7 @@
test(executor);
} finally {
executor.shutdown();
- executor.awaitTermination(30, SECONDS);
+ executor.awaitTermination(30L, SECONDS);
}
}
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -74,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,8 +38,20 @@
* @summary Times and checks basic map operations
*/
-import java.util.*;
-import java.io.*;
+import java.io.Serializable;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SplittableRandom;
public class MapCheck {
@@ -599,12 +611,11 @@
Stats(double t) { least = t; }
}
- static Random rng = new Random();
-
static void shuffle(Object[] keys) {
+ SplittableRandom rnd = new SplittableRandom();
int size = keys.length;
for (int i=size; i>1; i--) {
- int r = rng.nextInt(i);
+ int r = rnd.nextInt(i);
Object t = keys[i-1];
keys[i-1] = keys[r];
keys[r] = t;
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -44,15 +44,22 @@
* parsing from command line.)
*/
-import java.util.*;
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.List;
+import java.util.Map;
+import java.util.SplittableRandom;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
public class MapLoops {
- static int nkeys = 10000;
+ static int nkeys = 1000; // 10_000
static int pinsert = 60;
static int premove = 2;
static int maxThreads = 100;
- static int nops = 100000;
+ static int nops = 10000; // 100_000
static int removesPerMaxRandom;
static int insertsPerMaxRandom;
@@ -104,7 +111,6 @@
int k = 1;
int warmups = 2;
for (int i = 1; i <= maxThreads;) {
- Thread.sleep(100);
test(i, nkeys, mapClass);
if (warmups > 0)
--warmups;
@@ -120,7 +126,7 @@
i = k;
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
if (! throwables.isEmpty())
@@ -129,17 +135,17 @@
}
static Integer[] makeKeys(int n) {
- LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
+ SplittableRandom rnd = new SplittableRandom();
Integer[] key = new Integer[n];
for (int i = 0; i < key.length; ++i)
- key[i] = new Integer(rng.next());
+ key[i] = new Integer(rnd.nextInt());
return key;
}
static void shuffleKeys(Integer[] key) {
- Random rng = new Random();
+ SplittableRandom rnd = new SplittableRandom();
for (int i = key.length; i > 1; --i) {
- int j = rng.nextInt(i);
+ int j = rnd.nextInt(i);
Integer tmp = key[j];
key[j] = key[i-1];
key[i-1] = tmp;
@@ -155,8 +161,9 @@
// map.put(key[j], key[j]);
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(i+1, timer);
+ SplittableRandom rnd = new SplittableRandom();
for (int t = 0; t < i; ++t)
- pool.execute(new Runner(map, key, barrier));
+ pool.execute(new Runner(map, key, barrier, rnd.split()));
barrier.await();
barrier.await();
long time = timer.getTime();
@@ -170,21 +177,25 @@
static class Runner implements Runnable {
final Map<Integer,Integer> map;
final Integer[] key;
- final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
final CyclicBarrier barrier;
+ final SplittableRandom rnd;
int position;
int total;
- Runner(Map<Integer,Integer> map, Integer[] key, CyclicBarrier barrier) {
+ Runner(Map<Integer,Integer> map,
+ Integer[] key,
+ CyclicBarrier barrier,
+ SplittableRandom rnd) {
this.map = map;
this.key = key;
this.barrier = barrier;
+ this.rnd = rnd;
position = key.length / 2;
}
int step() {
// random-walk around key positions, bunching accesses
- int r = rng.next();
+ int r = rnd.nextInt(Integer.MAX_VALUE);
position += (r & 7) - 3;
while (position >= key.length) position -= key.length;
while (position < 0) position += key.length;
--- a/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentMap/ConcurrentModification.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,8 +27,11 @@
* @summary Reasonable things should happen if mutating while iterating.
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentSkipListMap;
public class ConcurrentModification {
static volatile int passed = 0, failed = 0;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,9 +38,25 @@
* @summary Checks that a set of threads can repeatedly get and modify items
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.atomic.AtomicInteger;
public class ConcurrentQueueLoops {
ExecutorService pool;
@@ -99,7 +115,7 @@
oneRun(i, items, q);
}
pool.shutdown();
- check(pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS));
+ check(pool.awaitTermination(60L, SECONDS));
}
class Stage implements Callable<Integer> {
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,15 +31,28 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
-import java.util.*;
-import java.util.concurrent.*;
-
/*
* @test
* @bug 6805775 6815766
* @summary Check weak consistency of concurrent queue iterators
*/
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+
@SuppressWarnings({"unchecked", "rawtypes"})
public class IteratorWeakConsistency {
final Random rnd = new Random();
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -74,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/OfferRemoveLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -29,10 +29,21 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.Arrays;
+import java.util.Queue;
+import java.util.SplittableRandom;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.ThreadLocalRandom;
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class OfferRemoveLoops {
@@ -61,10 +72,6 @@
testQueue(new LinkedTransferQueue());
}
- Random getRandom() {
- return ThreadLocalRandom.current();
- }
-
void testQueue(final Queue q) throws Throwable {
System.err.println(q.getClass().getSimpleName());
final long testDurationNanos = testDurationMillis * 1000L * 1000L;
@@ -73,13 +80,17 @@
final int maxChunkSize = 1042;
final int maxQueueSize = 10 * maxChunkSize;
final CountDownLatch done = new CountDownLatch(3);
+ final SplittableRandom rnd = new SplittableRandom();
/** Poor man's bounded buffer; prevents unbounded queue expansion. */
final Semaphore offers = new Semaphore(maxQueueSize);
abstract class CheckedThread extends Thread {
- CheckedThread(String name) {
+ final SplittableRandom rnd;
+
+ CheckedThread(String name, SplittableRandom rnd) {
super(name);
+ this.rnd = rnd;
setDaemon(true);
start();
}
@@ -97,9 +108,9 @@
}
}
- Thread offerer = new CheckedThread("offerer") {
+ Thread offerer = new CheckedThread("offerer", rnd.split()) {
protected void realRun() throws InterruptedException {
- final int chunkSize = getRandom().nextInt(maxChunkSize) + 20;
+ final int chunkSize = rnd.nextInt(maxChunkSize) + 20;
long c = 0;
while (! quittingTime()) {
if (q.offer(Long.valueOf(c))) {
@@ -113,9 +124,9 @@
done.countDown();
}};
- Thread remover = new CheckedThread("remover") {
+ Thread remover = new CheckedThread("remover", rnd.split()) {
protected void realRun() {
- final int chunkSize = getRandom().nextInt(maxChunkSize) + 20;
+ final int chunkSize = rnd.nextInt(maxChunkSize) + 20;
long c = 0;
while (! quittingTime()) {
if (q.remove(Long.valueOf(c))) {
@@ -131,9 +142,8 @@
done.countDown();
}};
- Thread scanner = new CheckedThread("scanner") {
+ Thread scanner = new CheckedThread("scanner", rnd.split()) {
protected void realRun() {
- final Random rnd = getRandom();
while (! quittingTime()) {
switch (rnd.nextInt(3)) {
case 0: checkNotContainsNull(q); break;
--- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/COWSubList.java Wed Dec 02 09:34:55 2015 -0800
@@ -26,6 +26,7 @@
* @bug 8011645
* @summary CopyOnWriteArrayList.COWSubList.subList does not validate range properly
*/
+
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
--- a/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArrayList/EqualsRace.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,10 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
public class EqualsRace {
private static void realMain(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CopyOnWriteArraySet/RacingCows.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,10 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
public class RacingCows {
private static void realMain(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/CountDownLatch/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CountDownLatch/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,7 +28,8 @@
* @author Seetharam Avadhanam, Martin Buchholz
*/
-import java.util.concurrent.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
interface AwaiterFactory {
--- a/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/CyclicBarrier/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,10 +28,17 @@
* @author Martin Buchholz, David Holmes
*/
-import java.util.*;
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
-import static java.util.concurrent.TimeUnit.*;
public class Basic {
--- a/jdk/test/java/util/concurrent/DelayQueue/Iterate.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/DelayQueue/Iterate.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,9 +28,11 @@
* @author Martin Buchholz
*/
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
public class Iterate {
private static class Godot implements Delayed {
--- a/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/DelayQueue/PollUnexpired.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,7 +28,9 @@
* @author Martin Buchholz
*/
-import java.util.concurrent.*;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
public class PollUnexpired {
private static class Godot implements Delayed {
--- a/jdk/test/java/util/concurrent/DelayQueue/Stress.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/DelayQueue/Stress.java Wed Dec 02 09:34:55 2015 -0800
@@ -21,8 +21,11 @@
* questions.
*/
-import java.util.concurrent.*;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
/**
* This is not a regression test, but a stress benchmark test for
--- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,7 +38,12 @@
* @summary checks to make sure a pipeline of exchangers passes data.
*/
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Exchanger;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
public class ExchangeLoops {
static final ExecutorService pool = Executors.newCachedThreadPool();
@@ -66,7 +71,7 @@
oneRun(i, iters);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,13 +30,12 @@
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -73,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,10 +38,15 @@
* @summary Exercise ExecutorCompletionServiceLoops
*/
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
public class ExecutorCompletionServiceLoops {
- static final int POOLSIZE = 100;
+ static final int POOLSIZE = 100;
static final ExecutorService pool =
Executors.newFixedThreadPool(POOLSIZE);
static final ExecutorCompletionService<Integer> ecs =
@@ -66,7 +71,7 @@
Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,13 +30,12 @@
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -73,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/ExecutorService/Invoke.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ExecutorService/Invoke.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,9 +28,13 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
public class Invoke {
static volatile int passed = 0, failed = 0;
--- a/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Executors/PrivilegedCallables.java Wed Dec 02 09:34:55 2015 -0800
@@ -29,10 +29,18 @@
* @author Martin Buchholz
*/
-import java.util.concurrent.*;
-import java.util.*;
-import java.security.*;
-import static java.util.concurrent.Executors.*;
+import static java.util.concurrent.Executors.privilegedCallable;
+import static java.util.concurrent.Executors.privilegedCallableUsingCurrentClassLoader;
+import static java.util.concurrent.Executors.privilegedThreadFactory;
+
+import java.security.AccessControlException;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.util.Random;
+import java.util.concurrent.Callable;
public class PrivilegedCallables {
Callable<Integer> real;
@@ -44,7 +52,7 @@
final Random rnd = new Random();
@SuppressWarnings("serial")
- Throwable[] throwables = {
+ final Throwable[] throwables = {
new Exception() {},
new RuntimeException() {},
new Error() {}
--- a/jdk/test/java/util/concurrent/Executors/Throws.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Executors/Throws.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,12 +28,24 @@
* @author Martin Buchholz
*/
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.*;
-import static java.util.concurrent.Executors.*;
+import static java.util.concurrent.Executors.callable;
+import static java.util.concurrent.Executors.defaultThreadFactory;
+import static java.util.concurrent.Executors.newCachedThreadPool;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static java.util.concurrent.Executors.newScheduledThreadPool;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static java.util.concurrent.Executors.privilegedCallable;
+import static java.util.concurrent.Executors.unconfigurableExecutorService;
+import static java.util.concurrent.Executors.unconfigurableScheduledExecutorService;
+
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
+import java.util.concurrent.Callable;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
public class Throws {
private static void realMain(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/BlockingTaskExecutor.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,13 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
/**
* Adapted from Doug Lea, which was...
@@ -71,7 +76,7 @@
// are blocked. This should cause the tasks to be
// interrupted.
executor.shutdownNow();
- if (! executor.awaitTermination(5, TimeUnit.SECONDS))
+ if (! executor.awaitTermination(5L, TimeUnit.SECONDS))
throw new Error("Executor stuck");
// Wait for the invocation thread to complete.
--- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -40,13 +40,21 @@
* TIMEOUT msecs to complete.
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.locks.ReentrantLock;
public final class CancelledFutureLoops {
static final ExecutorService pool = Executors.newCachedThreadPool();
- static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
+ static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
static final int ITERS = 1000000;
static final long TIMEOUT = 100;
@@ -61,7 +69,7 @@
for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) {
System.out.print("Threads: " + i);
try {
- new FutureLoop(i).test();
+ new FutureLoop(i, rnd.split()).test();
}
catch (BrokenBarrierException bb) {
// OK; ignore
@@ -72,19 +80,22 @@
Thread.sleep(TIMEOUT);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
static final class FutureLoop implements Callable {
- private int v = rng.next();
+ private final int nthreads;
+ private final SplittableRandom rnd;
private final ReentrantLock lock = new ReentrantLock();
private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
private final CyclicBarrier barrier;
- private final int nthreads;
- FutureLoop(int nthreads) {
+ private int v;
+ FutureLoop(int nthreads, SplittableRandom rnd) {
this.nthreads = nthreads;
+ this.rnd = rnd;
barrier = new CyclicBarrier(nthreads+1, timer);
+ v = rnd.nextInt();
}
final void test() throws Exception {
@@ -100,7 +111,7 @@
tooLate = true;
// Unbunch some of the cancels
if ( (i & 3) == 0)
- Thread.sleep(1 + rng.next() % 10);
+ Thread.sleep(1 + rnd.nextInt(5));
}
Object f0 = futures[0].get();
--- a/jdk/test/java/util/concurrent/FutureTask/Customized.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/Customized.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,9 +28,12 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicLong;
public class Customized {
static final AtomicLong doneCount = new AtomicLong(0);
--- a/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,9 +38,10 @@
* will never throw TimeoutException.
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
public class DoneTimedGetLoops {
@@ -141,8 +142,6 @@
failed++;
for (StackTraceElement e : thread.getStackTrace())
System.err.println(e);
- // Kludge alert
- thread.stop();
thread.join(timeoutMillis);
}
}
--- a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,13 +30,12 @@
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -73,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/FutureTask/Throw.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/FutureTask/Throw.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,7 +27,10 @@
* @summary Check exceptional behavior in run and done methods
*/
-import java.util.concurrent.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
public class Throw {
--- a/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/ToArray.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,8 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Collection;
+import java.util.concurrent.LinkedBlockingQueue;
public class ToArray {
public static void main(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/Phaser/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Phaser/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -39,13 +39,19 @@
* @author Chris Hegarty
*/
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
-import static java.util.concurrent.TimeUnit.*;
public class Basic {
@@ -86,25 +92,30 @@
//----------------------------------------------------------------
// Mechanism to get all test threads into "running" mode.
//----------------------------------------------------------------
- private static Phaser atTheStartingGate = new Phaser(3);
+ private static Phaser startingGate = new Phaser(3);
private static void toTheStartingGate() {
try {
- boolean expectNextPhase = false;
- if (atTheStartingGate.getUnarrivedParties() == 1) {
- expectNextPhase = true;
+ boolean expectNextPhase = (startingGate.getUnarrivedParties() == 1);
+ int phase = startingGate.getPhase();
+ equal(phase, startingGate.arrive());
+ int awaitPhase;
+ for (boolean interrupted = false;;) {
+ try {
+ awaitPhase = startingGate.awaitAdvanceInterruptibly
+ (phase, 30, SECONDS);
+ if (interrupted) Thread.currentThread().interrupt();
+ break;
+ } catch (InterruptedException ie) {
+ interrupted = true;
+ }
}
- int phase = atTheStartingGate.getPhase();
- equal(phase, atTheStartingGate.arrive());
- int awaitPhase = atTheStartingGate.awaitAdvanceInterruptibly
- (phase, 30, SECONDS);
if (expectNextPhase) check(awaitPhase == phase + 1);
else check(awaitPhase == phase || awaitPhase == phase + 1);
-
pass();
} catch (Throwable t) {
unexpected(t);
- // reset(atTheStartingGate);
+ // reset(startingGate);
throw new Error(t);
}
}
@@ -210,12 +221,23 @@
public void remove() {throw new UnsupportedOperationException();}};
}
+ static class SimpleTimer {
+ long startTime = System.nanoTime();
+ long elapsedMillis() {
+ long now = System.nanoTime();
+ long elapsed = NANOSECONDS.toMillis(now - startTime);
+ startTime = now;
+ return elapsed;
+ }
+ void printElapsed() { System.out.println(elapsedMillis() + " ms"); }
+ }
+
private static void realMain(String[] args) throws Throwable {
-
+ SimpleTimer timer = new SimpleTimer();
Thread.currentThread().setName("mainThread");
//----------------------------------------------------------------
- // Normal use
+ System.out.print("Normal use: ");
//----------------------------------------------------------------
try {
Phaser phaser = new Phaser(3);
@@ -243,9 +265,10 @@
equal(phaser.getArrivedParties(), 0);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // One thread interrupted
+ System.out.print("One thread interrupted: ");
//----------------------------------------------------------------
try {
Phaser phaser = new Phaser(3);
@@ -268,9 +291,10 @@
phase++;
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Phaser is terminated while threads are waiting
+ System.out.print("Phaser is terminated while threads are waiting: ");
//----------------------------------------------------------------
try {
for (int i = 0; i < 10; i++) {
@@ -291,9 +315,10 @@
equal(phaser.getArrivedParties(), arrivedParties);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Adds new unarrived parties to this phaser
+ System.out.print("Adds new unarrived parties to this phaser: ");
//----------------------------------------------------------------
try {
Phaser phaser = new Phaser(1);
@@ -301,7 +326,7 @@
LinkedList<Arriver> arriverList = new LinkedList<Arriver>();
int phase = phaser.getPhase();
for (int i = 1; i < 5; i++) {
- atTheStartingGate = new Phaser(1+(3*i));
+ startingGate = new Phaser(1+(3*i));
check(phaser.getPhase() == phase);
// register 3 more
phaser.register(); phaser.register(); phaser.register();
@@ -323,32 +348,34 @@
arriverList.clear();
phase++;
}
- atTheStartingGate = new Phaser(3);
+ startingGate = new Phaser(3);
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // One thread timed out
+ System.out.print("One thread timed out: ");
//----------------------------------------------------------------
try {
Phaser phaser = new Phaser(3);
Iterator<Arriver> arrivers = arriverIterator(phaser);
- for (long timeout : new long[] { 0L, 5L }) {
- for (int i = 0; i < 2; i++) {
- Awaiter a1 = awaiter(phaser, timeout, SECONDS); a1.start();
- Arriver a2 = arrivers.next(); a2.start();
- toTheStartingGate();
- a1.join();
- checkResult(a1, TimeoutException.class);
- phaser.arrive();
- a2.join();
- checkResult(a2, null);
- check(!phaser.isTerminated());
- }
+ for (long timeout : new long[] { 0L, 12L }) {
+ Awaiter a1 = awaiter(phaser, timeout, MILLISECONDS);
+ a1.start();
+ Arriver a2 = arrivers.next();
+ a2.start();
+ toTheStartingGate();
+ a1.join();
+ checkResult(a1, TimeoutException.class);
+ phaser.arrive();
+ a2.join();
+ checkResult(a2, null);
+ check(!phaser.isTerminated());
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Barrier action completed normally
+ System.out.print("Barrier action completed normally: ");
//----------------------------------------------------------------
try {
final AtomicInteger count = new AtomicInteger(0);
@@ -390,15 +417,43 @@
checkTerminated(phaser);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
}
//--------------------- Infrastructure ---------------------------
+
+ /**
+ * A debugging tool to print stack traces of most threads, as jstack does.
+ * Uninteresting threads are filtered out.
+ */
+ static void dumpTestThreads() {
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ System.err.println("------ stacktrace dump start ------");
+ for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+ String name = info.getThreadName();
+ if ("Signal Dispatcher".equals(name))
+ continue;
+ if ("Reference Handler".equals(name)
+ && info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
+ continue;
+ if ("Finalizer".equals(name)
+ && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
+ continue;
+ if ("process reaper".equals(name))
+ continue;
+ if (name != null && name.startsWith("ForkJoinPool.commonPool-worker"))
+ continue;
+ System.err.print(info);
+ }
+ System.err.println("------ stacktrace dump end ------");
+ }
+
static volatile int passed = 0, failed = 0;
static void pass() {passed++;}
static void fail() {failed++; Thread.dumpStack();}
static void fail(String msg) {System.out.println(msg); fail();}
- static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace(); dumpTestThreads();}
static void check(boolean cond) {if (cond) pass(); else fail();}
static void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass();
--- a/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Wed Dec 02 09:34:55 2015 -0800
@@ -37,9 +37,9 @@
* @run main FickleRegister 300
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.ArrayList;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.AtomicLong;
public class FickleRegister {
final AtomicLong count = new AtomicLong(0);
--- a/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -36,8 +36,8 @@
* @summary stress test for arrivals in a tiered phaser
* @run main TieredArriveLoops 300
*/
-import java.util.*;
-import java.util.concurrent.*;
+
+import java.util.concurrent.Phaser;
public class TieredArriveLoops {
final long testDurationMillisDefault = 10L * 1000L;
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,12 @@
* @summary Check effectiveness of RemoveOnCancelPolicy
*/
-import java.util.concurrent.*;
import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
/**
* Simple timer cancellation test. Submits tasks to a scheduled executor
@@ -60,7 +64,7 @@
equal(tpe.getActiveCount(), 0);
equal(tpe.getPoolSize(), 0);
equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
- check(tpe.awaitTermination(0, TimeUnit.SECONDS));
+ check(tpe.awaitTermination(0L, TimeUnit.SECONDS));
} catch (Throwable t) { unexpected(t); }
}
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DecorateTask.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,7 +27,13 @@
* @summary Test ScheduledThreadPoolExecutor.decorateTask
*/
-import java.util.concurrent.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
public class DecorateTask {
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Wed Dec 02 09:34:55 2015 -0800
@@ -37,7 +37,10 @@
* @summary Check for long overflow in task time comparison.
*/
-import java.util.concurrent.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class DelayOverflow {
static void waitForNanoTimeTick() {
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/GCRetention.java Wed Dec 02 09:34:55 2015 -0800
@@ -36,8 +36,14 @@
* @summary Ensure that waiting pool threads don't retain refs to tasks.
*/
-import java.lang.ref.*;
-import java.util.concurrent.*;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
public class GCRetention {
/**
@@ -110,7 +116,7 @@
Thread.sleep(10);
}
pool.shutdown();
- pool.awaitTermination(10, TimeUnit.SECONDS);
+ pool.awaitTermination(10L, TimeUnit.SECONDS);
if (cleared < size)
throw new Error(String.format
("references to %d/%d tasks retained (\"leaked\")",
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java Wed Dec 02 09:34:55 2015 -0800
@@ -21,7 +21,7 @@
* questions.
*/
-import java.util.concurrent.*;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
/**
* This is not a regression test, but a stress benchmark test for
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCoreThreads.java Wed Dec 02 09:34:55 2015 -0800
@@ -37,10 +37,14 @@
* @summary Ensure relative sanity when zero core threads
*/
-import java.util.concurrent.*;
-import static java.util.concurrent.TimeUnit.*;
-import java.util.concurrent.locks.*;
-import java.lang.reflect.*;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
public class ZeroCoreThreads {
static boolean hasWaiters(ReentrantLock lock, Condition condition) {
--- a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,8 +27,10 @@
* @summary Checks that fairness setting is respected.
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
public class Fairness {
private static void testFairness(boolean fair,
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java Wed Dec 02 09:34:55 2015 -0800
@@ -29,11 +29,19 @@
* @author Martin Buchholz
*/
-import java.security.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.security.Permission;
+import java.util.Random;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicInteger;
public class ConfigChanges {
static final ThreadGroup tg = new ThreadGroup("pool");
@@ -86,7 +94,7 @@
equal(tpe.getActiveCount(), 0);
equal(tpe.getPoolSize(), 0);
equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
- check(tpe.awaitTermination(0, SECONDS));
+ check(tpe.awaitTermination(0L, SECONDS));
} catch (Throwable t) { unexpected(t); }
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,7 +28,12 @@
* @author Martin Buchholz
*/
-import java.util.concurrent.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class CoreThreadTimeOut {
@@ -84,7 +89,7 @@
equal(countExecutorThreads(), 0);
tpe.shutdown();
check(tpe.allowsCoreThreadTimeOut());
- check(tpe.awaitTermination(10, TimeUnit.SECONDS));
+ check(tpe.awaitTermination(10L, TimeUnit.SECONDS));
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new Exception("Some tests failed");
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/Custom.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,15 @@
* @author Martin Buchholz
*/
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
public class Custom {
static volatile int passed = 0, failed = 0;
@@ -99,7 +106,7 @@
equal(countExecutorThreads(), threadCount);
equal(CustomTask.births.get(), threadCount);
tpe.shutdown();
- tpe.awaitTermination(120, TimeUnit.SECONDS);
+ tpe.awaitTermination(120L, TimeUnit.SECONDS);
Thread.sleep(1000);
equal(countExecutorThreads(), 0);
@@ -109,7 +116,7 @@
equal(CustomSTPE.decorations.get(), threadCount);
equal(countExecutorThreads(), threadCount);
stpe.shutdown();
- stpe.awaitTermination(120, TimeUnit.SECONDS);
+ stpe.awaitTermination(120L, TimeUnit.SECONDS);
Thread.sleep(1000);
equal(countExecutorThreads(), 0);
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/FlakyThreadFactory.java Wed Dec 02 09:34:55 2015 -0800
@@ -37,7 +37,10 @@
* @summary Should be able to shutdown a pool when worker creation failed.
*/
-import java.util.concurrent.*;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class FlakyThreadFactory {
void test(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ModifyCorePoolSize.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,7 +28,9 @@
* @author Martin Buchholz
*/
-import java.util.concurrent.*;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class ModifyCorePoolSize {
static void awaitPoolSize(ThreadPoolExecutor pool, int n) {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ScheduledTickleService.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,9 +30,18 @@
// based on a test kindly provided by Holger Hoffstaette <holger@wizards.de>
-import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
public class ScheduledTickleService {
// We get intermittent ClassCastException if greater than 1
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/SelfInterrupt.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,7 +27,10 @@
* @summary non-idle worker threads should not be interrupted
*/
-import java.util.concurrent.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class SelfInterrupt {
void test(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ShutdownNowExecuteRace.java Wed Dec 02 09:34:55 2015 -0800
@@ -33,8 +33,10 @@
// add a call to Thread.yield() before the call to t.start()
// in ThreadPoolExecutor.addWorker.
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class ShutdownNowExecuteRace {
static volatile boolean quit = false;
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThreadRestarts.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,9 +38,12 @@
* be kept alive to service a delayed task waiting in the queue.
*/
-import java.util.concurrent.*;
-import static java.util.concurrent.TimeUnit.*;
-import java.util.concurrent.atomic.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
public class ThreadRestarts {
public static void main(String[] args) throws Exception {
@@ -60,7 +63,8 @@
MILLISECONDS.sleep(100L);
} finally {
stpe.shutdownNow();
- stpe.awaitTermination(Long.MAX_VALUE, MILLISECONDS);
+ if (!stpe.awaitTermination(60L, SECONDS))
+ throw new AssertionError("timed out");
}
if (ctf.count.get() > 1)
throw new AssertionError(
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,10 +28,22 @@
* @author Martin Buchholz
*/
-import java.security.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
public class ThrowingTasks {
@@ -151,7 +163,7 @@
equal(tpe.getActiveCount(), 0);
equal(tpe.getPoolSize(), 0);
equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
- check(tpe.awaitTermination(0, TimeUnit.SECONDS));
+ check(tpe.awaitTermination(0L, TimeUnit.SECONDS));
} catch (Throwable t) { unexpected(t); }
}
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/TimeOutShrink.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,8 +28,10 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
public class TimeOutShrink {
static void checkPoolSizes(ThreadPoolExecutor pool,
@@ -61,7 +63,7 @@
Thread.sleep(100);
checkPoolSizes(pool, n, n, 2*n);
pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
+ check(pool.awaitTermination(60L, TimeUnit.SECONDS));
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/concurrent/TimeUnit/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/TimeUnit/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,10 +27,22 @@
* @author Martin Buchholz
*/
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.*;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
public class Basic {
private static void realMain(String[] args) throws Throwable {
--- a/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/atomic/AtomicUpdaters.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,9 +31,20 @@
* accessible fields in different locations with/without a security
* manager
*/
-import java.util.concurrent.atomic.*;
-import java.lang.reflect.*;
-import java.security.*;
+
+import java.lang.reflect.Field;
+import java.security.AccessControlException;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class AtomicUpdaters {
enum TYPE { INT, LONG, REF }
@@ -76,9 +87,9 @@
// Would like to test a public volatile in a class in another
// package - but of course there aren't any
- new Config(java.util.concurrent.atomic.AtomicInteger.class, "value", "private", hasSM ? false : true, false, "private int field of class in different package", TYPE.INT),
- new Config(java.util.concurrent.atomic.AtomicLong.class, "value", "private", hasSM ? false : true, false, "private long field of class in different package", TYPE.LONG),
- new Config(java.util.concurrent.atomic.AtomicReference.class, "value", "private", hasSM ? false : true, false, "private reference field of class in different package", TYPE.REF),
+ new Config(AtomicInteger.class, "value", "private", hasSM ? false : true, false, "private int field of class in different package", TYPE.INT),
+ new Config(AtomicLong.class, "value", "private", hasSM ? false : true, false, "private long field of class in different package", TYPE.LONG),
+ new Config(AtomicReference.class, "value", "private", hasSM ? false : true, false, "private reference field of class in different package", TYPE.REF),
};
}
--- a/jdk/test/java/util/concurrent/atomic/Lazy.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/atomic/Lazy.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,8 +27,16 @@
* @summary lazySet methods
*/
-import java.util.concurrent.atomic.*;
-import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class Lazy {
volatile int ii;
--- a/jdk/test/java/util/concurrent/atomic/Serial.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/atomic/Serial.java Wed Dec 02 09:34:55 2015 -0800
@@ -44,7 +44,6 @@
* Basic test to exercise the j.u.c.atomic classes that use serialization
* proxies.
*/
-
public class Serial {
public static void main(String[] args) {
--- a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Wed Dec 02 09:34:55 2015 -0800
@@ -36,17 +36,17 @@
* @author Doug Lea
* @bug 8004138
* @summary Check if ForkJoinPool table leaks thrown exceptions.
- * @run main/othervm/timeout=1200 -Xmx32m FJExceptionTableLeak
+ * @run main/othervm -Xmx2200k FJExceptionTableLeak
*/
-import java.util.concurrent.*;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveAction;
public class FJExceptionTableLeak {
- // TODO: make this test use less time!
-
- // Run with TASKS_PER_STEP * 40 < Xmx < STEPS * TASKS_PER_STEP * 40
- // These work for Xmx32m:
- static final int STEPS = 2000;
- static final int TASKS_PER_STEP = 1000;
+ // This test was observed to fail with jdk7 -Xmx2200k,
+ // using STEPS = 220 and TASKS_PER_STEP = 100
+ static final int STEPS = 500;
+ static final int TASKS_PER_STEP = 100;
static class FailingTaskException extends RuntimeException {}
static class FailingTask extends RecursiveAction {
--- a/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/CheckedLockLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,104 +34,72 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=7200 CheckedLockLoops
* @summary basic safety and liveness of ReentrantLocks, and other locks based on them
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
public final class CheckedLockLoops {
- static final ExecutorService pool = Executors.newCachedThreadPool();
- static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
- static boolean print = false;
- static boolean doBuiltin = false;
+ static ExecutorService pool;
+ static final SplittableRandom rnd = new SplittableRandom();
public static void main(String[] args) throws Exception {
- int maxThreads = 5;
- int iters = 100000;
-
- if (args.length > 0)
- maxThreads = Integer.parseInt(args[0]);
-
- rng.setSeed(3122688L);
+ final int maxThreads = (args.length > 0)
+ ? Integer.parseInt(args[0])
+ : 5;
+ int iters = 3000;
- print = false;
- System.out.println("Warmup...");
- oneTest(3, 10000);
- Thread.sleep(1000);
- oneTest(2, 10000);
- Thread.sleep(100);
- oneTest(1, 100000);
- Thread.sleep(100);
- oneTest(1, 100000);
- Thread.sleep(1000);
- print = true;
-
+ pool = Executors.newCachedThreadPool();
for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) {
- System.out.println("Threads:" + i);
oneTest(i, iters / i);
- Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(10L, SECONDS))
throw new Error();
+ pool = null;
}
static void oneTest(int nthreads, int iters) throws Exception {
- int v = rng.next();
- if (doBuiltin) {
- if (print)
- System.out.print("builtin lock ");
- new BuiltinLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- }
+ System.out.println("Threads: " + nthreads);
+ int v = rnd.nextInt();
+ System.out.print("builtin lock ");
+ new BuiltinLockLoop().test(v, nthreads, iters);
- if (print)
- System.out.print("ReentrantLock ");
+ System.out.print("ReentrantLock ");
new ReentrantLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("Mutex ");
+ System.out.print("Mutex ");
new MutexLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("ReentrantWriteLock ");
+ System.out.print("ReentrantWriteLock ");
new ReentrantWriteLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("ReentrantReadWriteLock");
+ System.out.print("ReentrantReadWriteLock");
new ReentrantReadWriteLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("Semaphore ");
+ System.out.print("Semaphore ");
new SemaphoreLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("fair Semaphore ");
+ System.out.print("fair Semaphore ");
new FairSemaphoreLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("FairReentrantLock ");
+ System.out.print("FairReentrantLock ");
new FairReentrantLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("FairRWriteLock ");
+ System.out.print("FairRWriteLock ");
new FairReentrantWriteLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
- if (print)
- System.out.print("FairRReadWriteLock ");
+ System.out.print("FairRReadWriteLock ");
new FairReentrantReadWriteLockLoop().test(v, nthreads, iters);
- Thread.sleep(10);
}
abstract static class LockLoop implements Runnable {
@@ -164,13 +132,11 @@
barrier.await();
barrier.await();
long time = timer.getTime();
- if (print) {
- long tpi = time / (iters * nthreads);
- System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update");
- // double secs = (double)(time) / 1000000000.0;
- // System.out.print("\t " + secs + "s run time");
- System.out.println();
- }
+ long tpi = time / (iters * nthreads);
+ System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update");
+ // double secs = (double)(time) / 1000000000.0;
+ // System.out.print("\t " + secs + "s run time");
+ System.out.println();
if (result == 0) // avoid overoptimization
System.out.println("useless result: " + result);
@@ -322,6 +288,7 @@
return sum;
}
}
+
private static class FairSemaphoreLoop extends LockLoop {
private final Semaphore sem = new Semaphore(1, true);
final int loop(int n) {
@@ -373,7 +340,6 @@
}
return sum;
}
-
}
private static class FairReentrantReadWriteLockLoop extends LockLoop {
@@ -407,6 +373,5 @@
}
return sum;
}
-
}
}
--- a/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/FlakyMutex.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,9 +28,14 @@
* @author Martin Buchholz
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
+import java.util.Random;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
/**
* This uses a variant of the standard Mutex demo, except with a
@@ -86,7 +91,7 @@
} catch (Throwable t) { unexpected(t); }}});}
barrier.await();
es.shutdown();
- check(es.awaitTermination(30, TimeUnit.SECONDS));
+ check(es.awaitTermination(30L, TimeUnit.SECONDS));
}
private static class FlakySync extends AbstractQueuedLongSynchronizer {
--- a/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,13 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -74,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/locks/Lock/Mutex.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/Mutex.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,11 +31,13 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.concurrent.atomic.*;
-import java.io.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.io.IOException;
+import java.io.ObjectInputStream;
/**
* A sample user extension of AbstractQueuedSynchronizer.
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquire.java Wed Dec 02 09:34:55 2015 -0800
@@ -26,7 +26,8 @@
* @summary Repeated timed tryAcquire shouldn't hang.
*/
-import java.util.concurrent.*;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
public class TimedAcquire {
public static void main(String[] args) throws Exception {
--- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java Wed Dec 02 09:34:55 2015 -0800
@@ -40,7 +40,7 @@
import java.io.PrintStream;
import java.io.Reader;
import java.lang.ref.WeakReference;
-import java.util.Random;
+import java.util.SplittableRandom;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
@@ -187,7 +187,7 @@
final String childClassName = Job.class.getName();
final String classToCheckForLeaks = Job.classToCheckForLeaks();
final String uniqueID =
- String.valueOf(new Random().nextInt(Integer.MAX_VALUE));
+ String.valueOf(new SplittableRandom().nextInt(Integer.MAX_VALUE));
final String[] jobCmd = {
java, "-Xmx8m", "-XX:+UsePerfData",
@@ -270,7 +270,7 @@
for (int i = 0; i < threads; i++)
new Thread() { public void run() {
try {
- final Random rnd = new Random();
+ final SplittableRandom rnd = new SplittableRandom();
for (int j = 0; j < iterations; j++) {
if (j == iterations/10 || j == iterations - 1) {
cb.await(); // Quiesce
--- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -41,6 +41,7 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
+import java.util.SplittableRandom;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -49,7 +50,7 @@
import java.util.concurrent.locks.LockSupport;
public final class ParkLoops {
- static final int THREADS = 4; // must be power of two
+ static final int THREADS = 4;
// static final int ITERS = 2_000_000;
// static final int TIMEOUT = 3500; // in seconds
static final int ITERS = 100_000;
@@ -64,18 +65,19 @@
private final AtomicReferenceArray<Thread> threads;
private final CountDownLatch done;
+ private final SplittableRandom rnd;
- Parker(AtomicReferenceArray<Thread> threads, CountDownLatch done) {
- this.threads = threads;
- this.done = done;
+ Parker(AtomicReferenceArray<Thread> threads,
+ CountDownLatch done,
+ SplittableRandom rnd) {
+ this.threads = threads; this.done = done; this.rnd = rnd;
}
public void run() {
- final SimpleRandom rng = new SimpleRandom();
final Thread current = Thread.currentThread();
for (int k = ITERS, j; k > 0; k--) {
do {
- j = rng.next() & (THREADS - 1);
+ j = rnd.nextInt(THREADS);
} while (!threads.compareAndSet(j, null, current));
do { // handle spurious wakeups
LockSupport.park();
@@ -94,16 +96,17 @@
private final AtomicReferenceArray<Thread> threads;
private final CountDownLatch done;
+ private final SplittableRandom rnd;
- Unparker(AtomicReferenceArray<Thread> threads, CountDownLatch done) {
- this.threads = threads;
- this.done = done;
+ Unparker(AtomicReferenceArray<Thread> threads,
+ CountDownLatch done,
+ SplittableRandom rnd) {
+ this.threads = threads; this.done = done; this.rnd = rnd;
}
public void run() {
- final SimpleRandom rng = new SimpleRandom();
for (int n = 0; (n++ & 0xff) != 0 || done.getCount() > 0;) {
- int j = rng.next() & (THREADS - 1);
+ int j = rnd.nextInt(THREADS);
Thread parker = threads.get(j);
if (parker != null &&
threads.compareAndSet(j, parker, null)) {
@@ -114,12 +117,13 @@
}
public static void main(String[] args) throws Exception {
+ final SplittableRandom rnd = new SplittableRandom();
final ExecutorService pool = Executors.newCachedThreadPool();
final AtomicReferenceArray<Thread> threads
= new AtomicReferenceArray<>(THREADS);
final CountDownLatch done = new CountDownLatch(THREADS);
- final Runnable parker = new Parker(threads, done);
- final Runnable unparker = new Unparker(threads, done);
+ final Runnable parker = new Parker(threads, done, rnd.split());
+ final Runnable unparker = new Unparker(threads, done, rnd.split());
for (int i = 0; i < THREADS; i++) {
pool.submit(parker);
pool.submit(unparker);
@@ -142,22 +146,4 @@
System.err.print(threadInfo);
}
}
-
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -33,51 +33,45 @@
/*
* @test
- * @bug 4486658
- * @run main/timeout=2800 CancelledLockLoops
+ * @bug 4486658 8040928 8140468
* @summary tests ReentrantLock.lockInterruptibly.
- * Checks for responsiveness of locks to interrupts. Runs under the
- * assumption that ITERS computations require more than TIMEOUT msecs
- * to complete.
+ * Checks for responsiveness of locks to interrupts.
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.locks.ReentrantLock;
public final class CancelledLockLoops {
- static final Random rng = new Random();
- static boolean print = false;
- static final int ITERS = 1000000;
- static final long TIMEOUT = 100;
+ static final SplittableRandom rnd = new SplittableRandom();
public static void main(String[] args) throws Exception {
- int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
-
- print = true;
+ final int maxThreads = (args.length > 0) ? Integer.parseInt(args[0]) : 5;
+ final int reps = 1; // increase for stress testing
- for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) {
- System.out.print("Threads: " + i);
- try {
- new ReentrantLockLoop(i).test();
+ for (int j = 0; j < reps; j++) {
+ for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) {
+ new Loops(i).test();
}
- catch (BrokenBarrierException bb) {
- // OK, ignore
- }
- Thread.sleep(TIMEOUT);
}
}
- static final class ReentrantLockLoop implements Runnable {
- private int v = rng.nextInt();
- private int completed;
+ static final class Loops implements Runnable {
+ private final boolean print = false;
+ private volatile boolean done = false;
+ private int v = rnd.nextInt();
+ private int completed = 0;
private volatile int result = 17;
private final ReentrantLock lock = new ReentrantLock();
private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
private final CyclicBarrier barrier;
private final int nthreads;
- ReentrantLockLoop(int nthreads) {
+ private volatile Throwable fail = null;
+ Loops(int nthreads) {
this.nthreads = nthreads;
+ if (print) System.out.print("Threads: " + nthreads);
barrier = new CyclicBarrier(nthreads+1, timer);
}
@@ -88,15 +82,15 @@
for (int i = 0; i < threads.length; ++i)
threads[i].start();
Thread[] cancels = threads.clone();
- Collections.shuffle(Arrays.asList(cancels), rng);
barrier.await();
- Thread.sleep(TIMEOUT);
+ Thread.sleep(rnd.nextInt(5));
for (int i = 0; i < cancels.length-2; ++i) {
cancels[i].interrupt();
// make sure all OK even when cancellations spaced out
if ( (i & 3) == 0)
- Thread.sleep(1 + rng.nextInt(10));
+ Thread.sleep(1 + rnd.nextInt(5));
}
+ done = true;
barrier.await();
if (print) {
long time = timer.getTime();
@@ -117,20 +111,25 @@
int r = result;
if (r == 0) // avoid overoptimization
System.out.println("useless result: " + r);
+ if (fail != null) throw new RuntimeException(fail);
}
public final void run() {
try {
barrier.await();
+ boolean interrupted = false;
+ long startTime = System.nanoTime();
int sum = v;
int x = 0;
- int n = ITERS;
- boolean done = false;
- do {
+ while (!done || Thread.currentThread().isInterrupted()) {
try {
lock.lockInterruptibly();
}
catch (InterruptedException ie) {
+ interrupted = true;
+ if (print)
+ System.out.printf("interrupted after %d millis%n",
+ NANOSECONDS.toMillis(System.nanoTime() - startTime));
break;
}
try {
@@ -140,8 +139,11 @@
lock.unlock();
}
sum += LoopHelpers.compute2(x);
- } while (n-- > 0);
- if (n <= 0) {
+ }
+ if (!interrupted) {
+ if (print)
+ System.out.printf("completed after %d millis%n",
+ NANOSECONDS.toMillis(System.nanoTime() - startTime));
lock.lock();
try {
++completed;
@@ -153,9 +155,9 @@
barrier.await();
result += sum;
}
- catch (Exception ex) {
- ex.printStackTrace();
- return;
+ catch (Throwable ex) {
+ fail = ex;
+ throw new RuntimeException(ex);
}
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,13 +38,17 @@
* @summary Checks for missed signals by locking and unlocking each of an array of locks once per thread
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.ReentrantLock;
public final class LockOncePerThreadLoops {
static final ExecutorService pool = Executors.newCachedThreadPool();
- static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
+ static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
static int nlocks = 50000;
static int nthreads = 100;
@@ -65,12 +69,12 @@
Thread.sleep(100);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
static final class ReentrantLockLoop implements Runnable {
- private int v = rng.next();
+ private int v = rnd.nextInt();
private volatile int result = 17;
final ReentrantLock[]locks = new ReentrantLock[nlocks];
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,13 +30,12 @@
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -73,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,13 +38,17 @@
* @summary multiple threads using a single lock
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.ReentrantLock;
public final class SimpleReentrantLockLoops {
static final ExecutorService pool = Executors.newCachedThreadPool();
- static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
+ static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
static int iters = 1000000;
@@ -66,12 +70,12 @@
}
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, SECONDS))
throw new Error();
}
static final class ReentrantLockLoop implements Runnable {
- private int v = rng.next();
+ private int v = rnd.nextInt();
private volatile int result = 17;
private final ReentrantLock lock = new ReentrantLock();
private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -33,27 +33,26 @@
/*
* @test
- * @bug 4486658 5031862
+ * @bug 4486658 5031862 8140471
* @run main TimeoutLockLoops
* @summary Checks for responsiveness of locks to timeouts.
- * Runs under the assumption that ITERS computations require more than
- * TIMEOUT msecs to complete, which seems to be a safe assumption for
- * another decade.
*/
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
public final class TimeoutLockLoops {
static final ExecutorService pool = Executors.newCachedThreadPool();
- static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
+ static final SplittableRandom rnd = new SplittableRandom();
static boolean print = false;
- static final int ITERS = Integer.MAX_VALUE;
- static final long TIMEOUT = 100;
+ static final long TIMEOUT = 10;
public static void main(String[] args) throws Exception {
- int maxThreads = 100;
+ int maxThreads = 8;
if (args.length > 0)
maxThreads = Integer.parseInt(args[0]);
@@ -62,21 +61,20 @@
for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) {
System.out.print("Threads: " + i);
new ReentrantLockLoop(i).test();
- Thread.sleep(10);
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(60L, TimeUnit.SECONDS))
throw new Error();
}
static final class ReentrantLockLoop implements Runnable {
- private int v = rng.next();
- private volatile boolean completed;
+ private int v = rnd.nextInt();
private volatile int result = 17;
private final ReentrantLock lock = new ReentrantLock();
private final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
private final CyclicBarrier barrier;
private final int nthreads;
+ private volatile Throwable fail = null;
ReentrantLockLoop(int nthreads) {
this.nthreads = nthreads;
barrier = new CyclicBarrier(nthreads+1, timer);
@@ -89,7 +87,7 @@
lock.unlock();
}
barrier.await();
- Thread.sleep(TIMEOUT);
+ Thread.sleep(rnd.nextInt(5));
while (!lock.tryLock()); // Jam lock
// lock.lock();
barrier.await();
@@ -99,11 +97,10 @@
System.out.println("\t " + secs + "s run time");
}
- if (completed)
- throw new Error("Some thread completed instead of timing out");
int r = result;
if (r == 0) // avoid overoptimization
System.out.println("useless result: " + r);
+ if (fail != null) throw new RuntimeException(fail);
}
public final void run() {
@@ -111,15 +108,8 @@
barrier.await();
int sum = v;
int x = 17;
- int n = ITERS;
final ReentrantLock lock = this.lock;
- for (;;) {
- if (x != 0) {
- if (n-- <= 0)
- break;
- }
- if (!lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS))
- break;
+ while (lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS)) {
try {
v = x = LoopHelpers.compute1(v);
}
@@ -128,14 +118,12 @@
}
sum += LoopHelpers.compute2(x);
}
- if (n <= 0)
- completed = true;
barrier.await();
result += sum;
}
- catch (Exception ex) {
- ex.printStackTrace();
- return;
+ catch (Throwable ex) {
+ fail = ex;
+ throw new RuntimeException(ex);
}
}
}
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Bug6571733.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,8 +27,9 @@
* @summary Check that regaining a read lock succeeds after a write
* lock attempt times out
*/
-import java.util.concurrent.locks.*;
-import java.util.concurrent.*;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Bug6571733 {
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java Wed Dec 02 09:34:55 2015 -0800
@@ -28,10 +28,20 @@
* @author Martin Buchholz
*/
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Random;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
// I am the Cownt, and I lahve to cownt.
public class Count {
@@ -92,7 +102,7 @@
barrier.await();
} catch (Throwable t) { unexpected(t); }}});}
es.shutdown();
- check(es.awaitTermination(10, TimeUnit.SECONDS));
+ check(es.awaitTermination(10L, TimeUnit.SECONDS));
}
void testReentrantLocks(final boolean fair,
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Wed Dec 02 09:34:55 2015 -0800
@@ -30,13 +30,12 @@
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Misc utilities in JSR166 performance tests
*/
-
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
class LoopHelpers {
// Some mindless computation to do between synchronizations...
@@ -73,28 +72,6 @@
return x;
}
- /**
- * An actually useful random number generator, but unsynchronized.
- * Basically same as java.util.Random.
- */
- public static class SimpleRandom {
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- static final AtomicLong seq = new AtomicLong(1);
- private long seed = System.nanoTime() + seq.getAndIncrement();
-
- public void setSeed(long s) {
- seed = s;
- }
-
- public int next() {
- long nextseed = (seed * multiplier + addend) & mask;
- seed = nextseed;
- return ((int)(nextseed >>> 17)) & 0x7FFFFFFF;
- }
- }
-
public static class BarrierTimer implements Runnable {
public volatile long startTime;
public volatile long endTime;
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Wed Dec 02 09:34:55 2015 -0800
@@ -34,7 +34,6 @@
/*
* @test
* @bug 4486658
- * @run main/timeout=4700 MapLoops
* @summary Exercise multithreaded maps, by default ConcurrentHashMap.
* Multithreaded hash table test. Each thread does a random walk
* though elements of "key" array. On each iteration, it checks if
@@ -44,15 +43,20 @@
* parsing from command line.)
*/
-import java.util.*;
-import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.Map;
+import java.util.SplittableRandom;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
public class MapLoops {
static final int NKEYS = 100000;
static int pinsert = 60;
static int premove = 2;
static int maxThreads = 5;
- static int nops = 1000000;
+ static int nops = 10000; // 1000000
static int removesPerMaxRandom;
static int insertsPerMaxRandom;
@@ -89,10 +93,10 @@
System.out.println("Using " + mapClass.getName());
- Random rng = new Random(315312);
+ SplittableRandom rnd = new SplittableRandom();
Integer[] key = new Integer[NKEYS];
for (int i = 0; i < key.length; ++i)
- key[i] = new Integer(rng.nextInt());
+ key[i] = new Integer(rnd.nextInt());
// warmup
System.out.println("Warmup...");
@@ -100,9 +104,8 @@
Map<Integer, Integer> map = (Map<Integer,Integer>)mapClass.newInstance();
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(1, timer);
- new Runner(map, key, barrier).run();
+ new Runner(map, key, barrier, rnd.split()).run();
map.clear();
- Thread.sleep(100);
}
for (int i = 1; i <= maxThreads; i += (i+1) >>> 1) {
@@ -111,7 +114,7 @@
LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
CyclicBarrier barrier = new CyclicBarrier(i+1, timer);
for (int k = 0; k < i; ++k)
- pool.execute(new Runner(map, key, barrier));
+ pool.execute(new Runner(map, key, barrier, rnd.split()));
barrier.await();
barrier.await();
long time = timer.getTime();
@@ -122,28 +125,32 @@
map.clear();
}
pool.shutdown();
- if (! pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS))
+ if (! pool.awaitTermination(10L, SECONDS))
throw new Error();
}
static class Runner implements Runnable {
final Map<Integer,Integer> map;
final Integer[] key;
- final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
final CyclicBarrier barrier;
+ final SplittableRandom rnd;
int position;
int total;
- Runner(Map<Integer,Integer> map, Integer[] key, CyclicBarrier barrier) {
+ Runner(Map<Integer,Integer> map,
+ Integer[] key,
+ CyclicBarrier barrier,
+ SplittableRandom rnd) {
this.map = map;
this.key = key;
this.barrier = barrier;
+ this.rnd = rnd;
position = key.length / 2;
}
int step() {
// random-walk around key positions, bunching accesses
- int r = rng.next();
+ int r = rnd.nextInt(Integer.MAX_VALUE);
position += (r & 7) - 3;
while (position >= key.length) position -= key.length;
while (position < 0) position += key.length;
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Wed Dec 02 09:34:55 2015 -0800
@@ -31,9 +31,11 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* This is an incomplete implementation of a wrapper class
--- a/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/concurrent/locks/StampedLock/Basic.java Wed Dec 02 09:34:55 2015 -0800
@@ -38,10 +38,13 @@
* @author Chris Hegarty
*/
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
import java.util.Iterator;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
-import static java.util.concurrent.TimeUnit.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
@@ -287,12 +290,34 @@
public void remove() {throw new UnsupportedOperationException();}};
}
- private static void realMain(String[] args) throws Throwable {
+ static class SimpleTimer {
+ long startTime = System.nanoTime();
+ long elapsedMillis() {
+ long now = System.nanoTime();
+ long elapsed = NANOSECONDS.toMillis(now - startTime);
+ startTime = now;
+ return elapsed;
+ }
+ void printElapsed() { System.out.println(elapsedMillis() + " ms"); }
+ }
- Thread.currentThread().setName("mainThread");
+ static void waitForThreadToBlock(Thread thread) {
+ for (long startTime = 0;;) {
+ Thread.State state = thread.getState();
+ if (state == Thread.State.WAITING ||
+ state == Thread.State.TIMED_WAITING)
+ break;
+ if (startTime == 0) startTime = System.nanoTime();
+ else if (System.nanoTime() - startTime > 10L * 1000L * 1000L * 1000L)
+ throw new AssertionError("timed out waiting for thread to block");
+ }
+ }
+
+ private static void realMain(String[] args) throws Throwable {
+ SimpleTimer timer = new SimpleTimer();
//----------------------------------------------------------------
- // Some basic sanity
+ System.out.print("Some basic sanity: ");
//----------------------------------------------------------------
try {
final StampedLock sl = new StampedLock();
@@ -309,10 +334,10 @@
check(!sl.isReadLocked());
check(sl.isWriteLocked());
check(sl.tryReadLock() == 0L);
- check(sl.tryReadLock(100, MILLISECONDS) == 0L);
+ check(sl.tryReadLock(1, MILLISECONDS) == 0L);
check(sl.tryOptimisticRead() == 0L);
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(100, MILLISECONDS) == 0L);
+ check(sl.tryWriteLock(1, MILLISECONDS) == 0L);
check(!sl.tryUnlockRead());
check(sl.tryConvertToWriteLock(stamp) == stamp);
try {
@@ -334,7 +359,7 @@
check(!sl.isWriteLocked());
check(sl.tryOptimisticRead() != 0L);
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(100, MILLISECONDS) == 0L);
+ check(sl.tryWriteLock(1, MILLISECONDS) == 0L);
check(!sl.tryUnlockWrite());
check(sl.tryConvertToReadLock(stamp) == stamp);
try {
@@ -349,105 +374,136 @@
}
check(!sl.isReadLocked());
- stamp = sl.tryReadLock(100, MILLISECONDS);
+ stamp = sl.tryReadLock(1, MILLISECONDS);
try {
check(stamp != 0L);
} finally {
sl.unlockRead(stamp);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Multiple writers single reader
+ System.out.print("Multiple writers single reader: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
- Phaser gate = new Phaser(102);
+ int nThreads = 10;
+ Phaser gate = new Phaser(nThreads + 2);
Iterator<Writer> writers = writerIterator(sl, gate);
Iterator<Reader> readers = readerIterator(sl, gate);
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 2; i++) {
check(!sl.isReadLocked());
check(!sl.isWriteLocked());
check(!sl.tryUnlockRead());
check(!sl.tryUnlockWrite());
check(sl.tryOptimisticRead() != 0L);
- Locker[] wThreads = new Locker[100];
- for (int j=0; j<100; j++)
+ Locker[] wThreads = new Locker[nThreads];
+ for (int j=0; j<nThreads; j++)
wThreads[j] = writers.next();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
wThreads[j].start();
Reader reader = readers.next(); reader.start();
toTheStartingGate(gate);
reader.join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
wThreads[j].join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
checkResult(wThreads[j], null);
checkResult(reader, null);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // Multiple readers single writer
+ System.out.print("Multiple readers single writer: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
- Phaser gate = new Phaser(102);
+ int nThreads = 10;
+ Phaser gate = new Phaser(nThreads + 2);
Iterator<Writer> writers = writerIterator(sl, gate);
Iterator<Reader> readers = readerIterator(sl, gate);
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 2; i++) {
check(!sl.isReadLocked());
check(!sl.isWriteLocked());
check(!sl.tryUnlockRead());
check(!sl.tryUnlockWrite());
check(sl.tryOptimisticRead() != 0L);
- Locker[] rThreads = new Locker[100];
- for (int j=0; j<100; j++)
+ Locker[] rThreads = new Locker[nThreads];
+ for (int j=0; j<nThreads; j++)
rThreads[j] = readers.next();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
rThreads[j].start();
Writer writer = writers.next(); writer.start();
toTheStartingGate(gate);
writer.join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
rThreads[j].join();
- for (int j=0; j<100; j++)
+ for (int j=0; j<nThreads; j++)
checkResult(rThreads[j], null);
checkResult(writer, null);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // thread interrupted
+ System.out.print("thread interrupted: ");
//----------------------------------------------------------------
try {
+ // We test interrupting both before and after trying to acquire
boolean view = false;
StampedLock sl = new StampedLock();
for (long timeout : new long[] { -1L, 30L, -1L, 30L }) {
- long stamp = sl.writeLock();
+ long stamp;
+ Thread.State state;
+
+ stamp = sl.writeLock();
try {
Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
r.start();
- // allow r to block
- Thread.sleep(2000);
r.interrupt();
r.join();
checkResult(r, InterruptedException.class);
} finally {
sl.unlockWrite(stamp);
}
+
+ stamp = sl.writeLock();
+ try {
+ Reader r = interruptibleReader(sl, timeout, SECONDS, null, view);
+ r.start();
+ waitForThreadToBlock(r);
+ r.interrupt();
+ r.join();
+ checkResult(r, InterruptedException.class);
+ } finally {
+ sl.unlockWrite(stamp);
+ }
+
stamp = sl.readLock();
try {
Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
w.start();
- // allow w to block
- Thread.sleep(2000);
w.interrupt();
w.join();
checkResult(w, InterruptedException.class);
} finally {
sl.unlockRead(stamp);
}
+
+ stamp = sl.readLock();
+ try {
+ Writer w = interruptibleWriter(sl, timeout, SECONDS, null, view);
+ w.start();
+ waitForThreadToBlock(w);
+ w.interrupt();
+ w.join();
+ checkResult(w, InterruptedException.class);
+ } finally {
+ sl.unlockRead(stamp);
+ }
+
check(!sl.isReadLocked());
check(!sl.isWriteLocked());
check(!sl.tryUnlockRead());
@@ -457,22 +513,23 @@
view = true;
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // timeout
+ System.out.print("timeout: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
for (long timeout : new long[] { 0L, 5L }) {
long stamp = sl.writeLock();
try {
- check(sl.tryReadLock(timeout, SECONDS) == 0L);
+ check(sl.tryReadLock(timeout, MILLISECONDS) == 0L);
} finally {
sl.unlockWrite(stamp);
}
stamp = sl.readLock();
try {
- check(sl.tryWriteLock(timeout, SECONDS) == 0L);
+ check(sl.tryWriteLock(timeout, MILLISECONDS) == 0L);
} finally {
sl.unlockRead(stamp);
}
@@ -483,9 +540,10 @@
check(sl.tryOptimisticRead() != 0L);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // optimistic read
+ System.out.print("optimistic read: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -510,9 +568,10 @@
check(sl.validate(stamp) == false);
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // convert
+ System.out.print("convert: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -527,12 +586,12 @@
check(sl.validate(stamp));
check(sl.isReadLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
check((stamp = sl.tryConvertToWriteLock(stamp)) != 0L);
check(sl.validate(stamp));
check(!sl.isReadLocked());
check(sl.isWriteLocked());
- check(sl.tryReadLock(1L, SECONDS) == 0L);
+ check(sl.tryReadLock(1L, MILLISECONDS) == 0L);
if (i != 0) {
sl.unlockWrite(stamp);
continue;
@@ -543,7 +602,7 @@
check(sl.isReadLocked());
check(!sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
check((stamp = sl.tryConvertToOptimisticRead(stamp)) != 0L);
check(sl.validate(stamp));
check(!sl.isReadLocked());
@@ -551,9 +610,10 @@
check(sl.validate(stamp));
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
//----------------------------------------------------------------
- // views
+ System.out.print("views: ");
//----------------------------------------------------------------
try {
StampedLock sl = new StampedLock();
@@ -566,7 +626,7 @@
check(sl.isReadLocked());
check(!sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
} finally {
rl.unlock();
}
@@ -578,7 +638,7 @@
check(!sl.isReadLocked());
check(sl.isWriteLocked());
check(sl.tryWriteLock() == 0L);
- check(sl.tryWriteLock(1L, SECONDS) == 0L);
+ check(sl.tryWriteLock(1L, MILLISECONDS) == 0L);
} finally {
wl.unlock();
}
@@ -590,6 +650,7 @@
wl = rwl.writeLock();
}
} catch (Throwable t) { unexpected(t); }
+ timer.printElapsed();
}
//--------------------- Infrastructure ---------------------------
--- a/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -128,7 +128,7 @@
int instanceCount = 0;
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine
- .attach(Integer.toString(ProcessTools.getProcessId()));
+ .attach(Long.toString(ProcessTools.getProcessId()));
try {
try (InputStream heapHistoStream = vm.heapHisto("-live");
BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) {
--- a/jdk/test/javax/management/remote/mandatory/loading/MethodResultTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/javax/management/remote/mandatory/loading/MethodResultTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,6 +27,7 @@
* @summary Tests client default class loader used before JSR 160 loader
* @author Eamonn McManus
* @modules java.management
+ * @library /lib/testlibrary
* @run clean MethodResultTest
* @run build MethodResultTest
* @run main MethodResultTest
@@ -38,6 +39,7 @@
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
+import jdk.testlibrary.Utils;
/*
This test checks that the class loader that is used to deserialize
@@ -124,7 +126,7 @@
}
cs.start();
JMXServiceURL addr = cs.getAddress();
- JMXConnector client = JMXConnectorFactory.connect(addr);
+ JMXConnector client = connect(addr);
MBeanServerConnection mbsc = client.getMBeanServerConnection();
Object getAttributeExotic = mbsc.getAttribute(on, "Exotic");
AttributeList getAttrs =
@@ -187,6 +189,32 @@
return ok;
}
+ private static JMXConnector connect(JMXServiceURL addr) {
+ final long timeout = Utils.adjustTimeout(100);
+
+ JMXConnector connector = null;
+ while (connector == null) {
+ try {
+ connector = JMXConnectorFactory.connect(addr);
+ } catch (IOException e) {
+ System.out.println("Connection error. Retrying after delay...");
+ delay(timeout);
+ } catch (Exception otherException) {
+ System.out.println("Unexpected exception while connecting " + otherException);
+ throw new RuntimeException(otherException);
+ }
+ }
+ return connector;
+ }
+
+ private static void delay(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static Exception noException(String what) {
final String msg =
"Operation " + what + " returned when exception expected";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @run main/othervm SSLEngineAlpnTest h2 h2 h2
+ * @run main/othervm SSLEngineAlpnTest h2 h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest h2,http/1.1 h2,http/1.1 h2
+ * @run main/othervm SSLEngineAlpnTest http/1.1,h2 h2,http/1.1 http/1.1
+ * @run main/othervm SSLEngineAlpnTest h4,h3,h2 h1,h2 h2
+ * @run main/othervm SSLEngineAlpnTest EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLEngineAlpnTest h2 EMPTY NONE
+ * @run main/othervm SSLEngineAlpnTest H2 h2 ERROR
+ * @run main/othervm SSLEngineAlpnTest h2 http/1.1 ERROR
+ */
+/**
+ * A simple SSLEngine-based client/server that demonstrates the proposed API
+ * changes for JEP 244 in support of the TLS ALPN extension (RFC 7301).
+ *
+ * This example is based on our standard SSLEngineTemplate.
+ *
+ * The immediate consumer of ALPN will be HTTP/2 (RFC 7540), aka H2. The H2 IETF
+ * Working Group wanted to use TLSv1.3+ as the secure transport mechanism, but
+ * TLSv1.3 wasn't ready. The H2 folk agreed to a compromise that only TLSv1.2+
+ * can be used, and that if TLSv1.2 was selected, non-TLSv.1.3-approved
+ * ciphersuites would be blacklisted and their use discouraged.
+ *
+ * In order to support connections that might negotiate either HTTP/1.1 and H2,
+ * the guidance from the IETF Working Group is that the H2 ciphersuites be
+ * prioritized/tried first.
+ */
+
+/*
+ * The original SSLEngineTemplate comments follow.
+ *
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+
+public class SSLEngineAlpnTest {
+
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+
+ private final SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static final String pathToStores = "../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ private static final String keyFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + keyStoreFile;
+ private static final String trustFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + trustStoreFile;
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ // Validate parameters
+ if (args.length != 3) {
+ throw new Exception("Invalid number of test parameters");
+ }
+
+ SSLEngineAlpnTest test = new SSLEngineAlpnTest();
+ try {
+ test.runTest(convert(args[0]), convert(args[1]), args[2]);
+ } catch (SSLHandshakeException she) {
+ if (args[2].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public SSLEngineAlpnTest() throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ String[] strings = null;
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest(String[] serverAPs, String[] clientAPs,
+ String expectedAP) throws Exception {
+
+ boolean dataDone = false;
+
+ createSSLEngines(serverAPs, clientAPs);
+ createBuffers();
+
+ SSLEngineResult clientResult; // results from client's last operation
+ SSLEngineResult serverResult; // results from server's last operation
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ while (!isEngineClosed(clientEngine)
+ || !isEngineClosed(serverEngine)) {
+
+ log("================");
+
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ checkAPResult(clientEngine, clientResult, expectedAP);
+
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ checkAPResult(serverEngine, serverResult, expectedAP);
+
+ cTOs.flip();
+ sTOc.flip();
+
+ log("----");
+
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ checkAPResult(clientEngine, clientResult, expectedAP);
+
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ checkAPResult(serverEngine, serverResult, expectedAP);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ /*
+ * After we've transfered all application data between the client
+ * and server, we close the clientEngine's outbound stream.
+ * This generates a close_notify handshake message, which the
+ * server engine receives and responds by closing itself.
+ */
+ if (!dataDone && (clientOut.limit() == serverIn.position())
+ && (serverOut.limit() == clientIn.position())) {
+
+ /*
+ * A sanity check to ensure we got what was sent.
+ */
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+
+ log("\tClosing clientEngine's *OUTBOUND*...");
+ clientEngine.closeOutbound();
+ dataDone = true;
+ }
+ }
+ }
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ *
+ * If we were expecting an ALPN value from server, let's make sure
+ * the conditions match.
+ */
+ private static void checkAPResult(SSLEngine engine, SSLEngineResult result,
+ String expectedAP) throws Exception {
+
+ if (result.getHandshakeStatus() != HandshakeStatus.FINISHED) {
+ return;
+ }
+
+ String ap = engine.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP +
+ " ALPN value not available on negotiated connection");
+ }
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngines(String[] serverAPs, String[] clientAPs)
+ throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+
+ SSLParameters sslp = serverEngine.getSSLParameters();
+
+ sslp.setNeedClientAuth(true);
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setApplicationProtocols(serverAPs);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ serverEngine.setSSLParameters(sslp);
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+ sslp = clientEngine.getSSLParameters();
+ sslp.setApplicationProtocols(clientAPs);
+ clientEngine.setSSLParameters(sslp);
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers() {
+
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n"
+ + "\t\"getStatus() / getHandshakeStatus()\" +\n"
+ + "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str
+ + result.getStatus() + "/" + hsStatus + ", "
+ + result.bytesConsumed() + "/" + result.bytesProduced()
+ + " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @run main/othervm SSLSocketAlpnTest h2 h2 h2
+ * @run main/othervm SSLSocketAlpnTest h2 h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest h2,http/1.1 h2,http/1.1 h2
+ * @run main/othervm SSLSocketAlpnTest http/1.1,h2 h2,http/1.1 http/1.1
+ * @run main/othervm SSLSocketAlpnTest h4,h3,h2 h1,h2 h2
+ * @run main/othervm SSLSocketAlpnTest EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLSocketAlpnTest h2 EMPTY NONE
+ * @run main/othervm SSLSocketAlpnTest H2 h2 ERROR
+ * @run main/othervm SSLSocketAlpnTest h2 http/1.1 ERROR
+ * @author Brad Wetmore
+ */
+import java.io.*;
+import javax.net.ssl.*;
+
+public class SSLSocketAlpnTest {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ static String[] serverAPs;
+ static String[] clientAPs;
+ static String expectedAP;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf
+ = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ SSLServerSocket sslServerSocket
+ = (SSLServerSocket) sslssf.createServerSocket(serverPort);
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(serverAPs);
+ sslSocket.setSSLParameters(sslp);
+
+ sslSocket.startHandshake();
+
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP +
+ " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf
+ = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket
+ = (SSLSocket) sslsf.createSocket("localhost", serverPort);
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(clientAPs);
+ sslSocket.setSSLParameters(sslp);
+
+ sslSocket.startHandshake();
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ *
+ * We were expecting H2 from server, let's make sure the
+ * conditions match.
+ */
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP +
+ " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ String keyFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + keyStoreFile;
+ String trustFilename
+ = System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ // Validate parameters
+ if (args.length != 3) {
+ throw new Exception("Invalid number of test parameters");
+ }
+ serverAPs = convert(args[0]);
+ clientAPs = convert(args[1]);
+ expectedAP = args[2];
+
+ /*
+ * Start the tests.
+ */
+ try {
+ new SSLSocketAlpnTest();
+ } catch (SSLHandshakeException she) {
+ if (args[2].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ String[] strings;
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SSLSocketAlpnTest() throws Exception {
+ Exception startException = null;
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- a/jdk/test/javax/net/ssl/SSLSession/SessionTimeOutTests.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/javax/net/ssl/SSLSession/SessionTimeOutTests.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -36,6 +36,7 @@
import javax.net.ssl.*;
import java.util.*;
import java.security.*;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Session reuse time-out tests cover the cases below:
@@ -79,7 +80,7 @@
/*
* Is the server ready to serve?
*/
- volatile static int serverReady = PORTS;
+ AtomicInteger serverReady = new AtomicInteger(PORTS);
/*
* Turn on SSL debugging?
@@ -98,7 +99,7 @@
/*
* Define the server side of the test.
*
- * If the server prematurely exits, serverReady will be set to true
+ * If the server prematurely exits, serverReady will be set to zero
* to avoid infinite hangs.
*/
@@ -116,7 +117,7 @@
/*
* Signal Client, we're ready for his connect.
*/
- serverReady--;
+ serverReady.getAndDecrement();
int read = 0;
int nConnections = 0;
SSLSession sessions [] = new SSLSession [serverConns];
@@ -137,7 +138,7 @@
/*
* Define the client side of the test.
*
- * If the server prematurely exits, serverReady will be set to true
+ * If the server prematurely exits, serverReady will be set to zero
* to avoid infinite hangs.
*/
void doClientSide() throws Exception {
@@ -145,7 +146,7 @@
/*
* Wait for server to get started.
*/
- while (serverReady > 0) {
+ while (serverReady.get() > 0) {
Thread.sleep(50);
}
@@ -447,7 +448,7 @@
*/
System.err.println("Server died...");
e.printStackTrace();
- serverReady = 0;
+ serverReady.set(0);
serverException = e;
}
}
@@ -459,7 +460,7 @@
} catch (Exception e) {
serverException = e;
} finally {
- serverReady = 0;
+ serverReady.set(0);
}
}
}
--- a/jdk/test/javax/net/ssl/templates/SSLEngineTemplate.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/javax/net/ssl/templates/SSLEngineTemplate.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -78,7 +78,7 @@
/*
* Enables logging of the SSLEngine operations.
*/
- private static boolean logging = true;
+ private static final boolean logging = true;
/*
* Enables the JSSE system debugging system property:
@@ -89,9 +89,9 @@
* including specific handshake messages, and might be best examined
* after gaining some familiarity with this application.
*/
- private static boolean debug = false;
+ private static final boolean debug = false;
- private SSLContext sslc;
+ private final SSLContext sslc;
private SSLEngine clientEngine; // client Engine
private ByteBuffer clientOut; // write side of clientEngine
@@ -112,15 +112,15 @@
/*
* The following is to set up the keystores.
*/
- private static String pathToStores = "../etc";
- private static String keyStoreFile = "keystore";
- private static String trustStoreFile = "truststore";
- private static String passwd = "passphrase";
+ private static final String pathToStores = "../etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
- private static String keyFilename =
+ private static final String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
- private static String trustFilename =
+ private static final String trustFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + trustStoreFile;
--- a/jdk/test/javax/net/ssl/templates/SSLSocketSSLEngineTemplate.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/javax/net/ssl/templates/SSLSocketSSLEngineTemplate.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -86,7 +86,7 @@
/*
* Enables logging of the SSL/TLS operations.
*/
- private static boolean logging = true;
+ private static final boolean logging = true;
/*
* Enables the JSSE system debugging system property:
@@ -97,8 +97,8 @@
* including specific handshake messages, and might be best examined
* after gaining some familiarity with this application.
*/
- private static boolean debug = false;
- private SSLContext sslc;
+ private static final boolean debug = false;
+ private final SSLContext sslc;
private SSLEngine serverEngine; // server-side SSLEngine
private SSLSocket sslSocket; // client-side socket
private ServerSocket serverSocket; // server-side Socket, generates the...
@@ -128,10 +128,10 @@
private static final String keyStoreFile = "keystore";
private static final String trustStoreFile = "truststore";
private static final String passwd = "passphrase";
- private static String keyFilename =
+ private static final String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores
+ "/" + keyStoreFile;
- private static String trustFilename =
+ private static final String trustFilename =
System.getProperty("test.src", ".") + "/" + pathToStores
+ "/" + trustStoreFile;
@@ -252,7 +252,7 @@
byte[] outbound = new byte[8192];
while (!isEngineClosed(serverEngine)) {
- int len = 0;
+ int len;
// Inbound data
log("================");
@@ -326,7 +326,6 @@
serverIn.compact();
}
}
- return;
} catch (Exception e) {
serverException = e;
} finally {
@@ -384,13 +383,12 @@
int pos = 0;
int len;
-done:
while ((len = is.read(inbound, pos, 2048 - pos)) != -1) {
pos += len;
// Let the client do the closing.
if ((pos == serverMsg.length) && !serverClose) {
sslSocket.close();
- break done;
+ break;
}
}
--- a/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -33,7 +33,6 @@
*/
import java.io.*;
-import java.net.*;
import javax.net.ssl.*;
public class SSLSocketTemplate {
@@ -162,8 +161,9 @@
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
- if (debug)
+ if (debug) {
System.setProperty("javax.net.debug", "all");
+ }
/*
* Start the tests.
@@ -255,6 +255,7 @@
void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
+ @Override
public void run() {
try {
doServerSide();
@@ -285,6 +286,7 @@
void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
+ @Override
public void run() {
try {
doClientSide();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/SAAJFactoryTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.xml.soap.MessageFactory;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+
+/*
+ * @test
+ * @bug 8131334
+ * @summary SAAJ Plugability Layer: using java.util.ServiceLoader
+ *
+ * There are unsafe scenarios not to be run within jdk build (relying on global jdk confguration)
+ *
+ * unsafe; not running:
+ *
+ * run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario1 javax.xml.soap.MessageFactory=saaj.factory.Valid -
+ * run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario3 javax.xml.soap.MessageFactory=non.existing.FactoryClass -
+ * run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario4 javax.xml.soap.MessageFactory=saaj.factory.Invalid -
+ * run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Valid3 SAAJFactoryTest saaj.factory.Valid3 -
+ * scenario13 javax.xml.soap.MessageFactory=saaj.factory.Valid saaj.factory.Valid2
+ * run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario14 javax.xml.soap.MessageFactory=saaj.factory.Valid saaj.factory.Valid2 -
+ *
+ * @build saaj.factory.*
+ *
+ * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl -
+ * scenario2 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Valid SAAJFactoryTest saaj.factory.Valid -
+ * scenario5 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.NonExisting SAAJFactoryTest
+ * - javax.xml.soap.SOAPException
+ * scenario6 - -
+ * @run main/othervm -Djavax.xml.soap.MessageFactory=saaj.factory.Invalid SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario7 - -
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario8 - saaj.factory.Valid
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario9 - saaj.factory.Valid
+ * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario10 - saaj.factory.NonExisting
+ * @run main/othervm SAAJFactoryTest - javax.xml.soap.SOAPException
+ * scenario11 - saaj.factory.Invalid
+ * @run main/othervm SAAJFactoryTest com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl -
+ * scenario12 - -
+ * @run main/othervm SAAJFactoryTest saaj.factory.Valid -
+ * scenario15 - saaj.factory.Valid
+ */
+public class SAAJFactoryTest {
+
+ // scenario name - just for logging
+ static String scenario;
+
+ // configuration to be created by the test
+ static Path providersDir = Paths.get(System.getProperty("test.classes"), "META-INF", "services");
+ static Path providersFile = providersDir.resolve("javax.xml.soap.MessageFactory");
+
+ // configuration to be created by the test
+ static Path jdkDir = Paths.get(System.getProperty("java.home"), "conf");
+ static Path jdkFile = jdkDir.resolve("jaxm.properties");
+
+ // java policy file for testing w/security manager
+ static String policy = System.getProperty("test.src", ".") + File.separator + "test.policy";
+
+
+ protected MessageFactory factory() throws Throwable {
+ try {
+ MessageFactory factory = MessageFactory.newInstance();
+ System.out.println(" TEST: factory class = [" + factory.getClass().getName() + "]\n");
+ return factory;
+ } catch (Throwable t) {
+ System.out.println(" TEST: Throwable [" + t.getClass().getName() + "] thrown.\n");
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ protected void test(String[] args) {
+ if (args.length < 5) throw new IllegalArgumentException("Incorrect test setup. Required 5 arguments: \n" +
+ " 1. expected factory class (if any)\n" +
+ " 2. expected \n" +
+ " 3. scenario name\n" +
+ " 4. jdk/conf configured provider class name\n" +
+ " 5. service loader provider class name");
+
+ scenario = args[2]; // scenario name
+ prepare(args[3], args[4]); // jdk/conf class, service loader class
+
+ try {
+ MessageFactory factory = factory();
+ assertTrue(factory != null, "No factory found.");
+ String className = factory.getClass().getName();
+ assertTrue(args[0].equals(className), "Incorrect factory: [" + className +
+ "], Expected: [" + args[0] + "]");
+
+ } catch (Throwable throwable) {
+ String expectedExceptionClass = args[1];
+ String throwableClass = throwable.getClass().getName();
+ boolean correctException = throwableClass.equals(expectedExceptionClass);
+ if (!correctException) {
+ throwable.printStackTrace();
+ }
+ assertTrue(correctException, "Got unexpected exception: [" +
+ throwableClass + "], expected: [" + expectedExceptionClass + "]");
+ } finally {
+ cleanResource(providersFile);
+ cleanResource(providersDir);
+
+ // unsafe; not running:
+ // cleanResource(jdkFile);
+ }
+ }
+
+ private void cleanResource(Path resource) {
+ try {
+ Files.deleteIfExists(resource);
+ } catch (IOException ignored) {
+ ignored.printStackTrace();
+ }
+ }
+
+ private void prepare(String propertiesClassName, String providerClassName) {
+
+ try {
+ log("providerClassName = " + providerClassName);
+ log("propertiesClassName = " + propertiesClassName);
+
+ setupFile(providersFile, providersDir, providerClassName);
+
+ // unsafe; not running:
+ //setupFile(jdkFile, jdkDir, propertiesClassName);
+
+ log(" SETUP OK.");
+
+ } catch (IOException e) {
+ log(" SETUP FAILED.");
+ e.printStackTrace();
+ }
+ }
+
+ private void setupFile(Path file, Path dir, String value) throws IOException {
+ cleanResource(file);
+ if (!"-".equals(value)) {
+ log("writing configuration [" + value + "] into file [" + file.toAbsolutePath() + "]");
+ Files.createDirectories(dir);
+ Files.write(
+ file,
+ value.getBytes(),
+ StandardOpenOption.CREATE);
+ }
+ }
+
+ private static void assertTrue(boolean condition, String msg) {
+ if (!condition) {
+ log(" FAILED - ERROR: " + msg);
+ throw new RuntimeException("[" + scenario + "] " + msg);
+ } else {
+ log(" PASSED.");
+ }
+ }
+
+ private static void log(String msg) {
+ System.out.println("[" + scenario + "] " + msg);
+ }
+
+
+ public static void main(String[] args) {
+ // no security manager
+ new SAAJFactoryTest().test(args);
+
+ System.out.println("Policy file: " + policy);
+ System.setProperty("java.security.policy", policy);
+
+ System.out.println("Install security manager...");
+ System.setSecurityManager(new SecurityManager());
+
+ // security manager enabled
+ new SAAJFactoryTest().test(args);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Invalid.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package saaj.factory;
+
+/**
+ * Invalid implementation class for tests
+ * - doesn't contain required static methods
+ */
+public class Invalid {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package saaj.factory;
+
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid2.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package saaj.factory;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * (Another) Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid2 extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/saaj/factory/Valid3.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package saaj.factory;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * (Another) Valid implementation class for tests
+ * - several implementations necessary to test different configuration approaches
+ */
+public class Valid3 extends MessageFactory {
+ @Override
+ public SOAPMessage createMessage() throws SOAPException {
+ return null;
+ }
+
+ @Override
+ public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/soap/spi/test.policy Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,7 @@
+grant {
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "${test.classes}${/}-", "read, write, delete";
+
+ // unsafe; not running:
+ //permission java.io.FilePermission "${java.home}${/}-", "read, write, delete";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/security/JavaDotSecurity/final_java_security Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,22 @@
+#
+# This is my own security properties file.
+#
+
+foo.1=1
+foo.2=4
+foo.3=5
+foo.4=6a
+foo.5=8
+foo.6=9a
+foo.7=10
+foo.8=12
+
+package.access=sun.,\
+ solaris.,\
+ one.more,\
+ two.more
+
+package.definition=sun.,\
+ solaris.,\
+ one.more,\
+ two.more,\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/security/JavaDotSecurity/ifdefs.sh Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# @test
+# @bug 8141690
+# @summary MakeJavaSecurity.java functions
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+ COMPILEJAVA=${TESTJAVA}
+fi
+
+JAVAC="${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS}"
+JAVA="${TESTJAVA}/bin/java ${TESTVMOPTS}"
+TOOLSRC="${TESTSRC}/../../../../make/src/classes/build/tools/makejavasecurity/MakeJavaSecurity.java"
+TOOLNAME=build.tools.makejavasecurity.MakeJavaSecurity
+
+if [ ! -f $TOOLSRC ]; then
+ echo "Cannot find $TOOLSRC. Maybe not all code repos are available"
+ exit 0
+fi
+
+$JAVAC -d . $TOOLSRC
+$JAVA $TOOLNAME $TESTSRC/raw_java_security outfile solaris sparc $TESTSRC/more_restricted
+
+# On Windows, line end could be different. -b is a cross-platform option.
+diff -b outfile $TESTSRC/final_java_security
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/security/JavaDotSecurity/more_restricted Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,2 @@
+one.more
+two.more
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/security/JavaDotSecurity/raw_java_security Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,62 @@
+#
+# This is my own security properties file.
+#
+
+#ifdef solaris
+foo.tbd=1
+#else
+foo.tbd=1a
+#endif
+#ifndef solaris
+foo.tbd=2
+#endif
+#ifdef mac
+foo.tbd=3
+#endif
+#ifndef mac
+foo.tbd=4
+#endif
+#ifdef solaris-sparc
+foo.tbd=5
+#endif
+#ifndef solaris-sparc
+foo.tbd=6
+#else
+foo.tbd=6a
+#endif
+#ifdef solaris-x64
+foo.tbd=7
+#endif
+#ifndef solaris-x64
+foo.tbd=8
+#endif
+#ifdef macosx-sparc
+foo.tbd=9
+#else
+foo.tbd=9a
+#endif
+#ifndef macosx-sparc
+foo.tbd=10
+#endif
+#ifdef macosx-x64
+foo.tbd=11
+#endif
+#ifndef macosx-x64
+foo.tbd=12
+#endif
+
+package.access=sun.,\
+#ifdef solaris
+ solaris.,\
+#endif
+#ifdef macosx
+ apple.,\
+#endif
+
+package.definition=sun.,\
+#ifdef solaris
+ solaris.,\
+#endif
+#ifdef macosx
+ apple.,\
+#endif
--- a/jdk/test/jdk/security/jarsigner/Function.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/jdk/security/jarsigner/Function.java Wed Dec 02 09:34:55 2015 -0800
@@ -71,13 +71,17 @@
" -keypass changeit -dname" +
" CN=RSA -alias r -genkeypair -keyalg rsa").split(" "));
- KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream("ks"), "changeit".toCharArray());
- PrivateKey key = (PrivateKey)ks.getKey("r", "changeit".toCharArray());
- Certificate cert = ks.getCertificate("r");
- JarSigner.Builder jsb = new JarSigner.Builder(key,
- CertificateFactory.getInstance("X.509").generateCertPath(
- Collections.singletonList(cert)));
+ JarSigner.Builder jsb;
+
+ try (FileInputStream fis = new FileInputStream("ks")) {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(fis, "changeit".toCharArray());
+ PrivateKey key = (PrivateKey)ks.getKey("r", "changeit".toCharArray());
+ Certificate cert = ks.getCertificate("r");
+ jsb = new JarSigner.Builder(key,
+ CertificateFactory.getInstance("X.509").generateCertPath(
+ Collections.singletonList(cert)));
+ }
jsb.digestAlgorithm("SHA1");
jsb.signatureAlgorithm("SHA1withRSA");
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/InputArguments.java Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.testlibrary;
-
-import java.lang.management.RuntimeMXBean;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-/**
- * This class provides access to the input arguments to the VM.
- */
-public class InputArguments {
- private static final List<String> args;
-
- static {
- RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
- args = runtimeMxBean.getInputArguments();
- }
-
- /**
- * Returns true if {@code arg} is an input argument to the VM.
- *
- * This is useful for checking boolean flags such as -XX:+UseSerialGC or
- * -XX:-UsePerfData.
- *
- * @param arg The name of the argument.
- * @return {@code true} if the given argument is an input argument,
- * otherwise {@code false}.
- */
- public static boolean contains(String arg) {
- return args.contains(arg);
- }
-
- /**
- * Returns true if {@code prefix} is the start of an input argument to the
- * VM.
- *
- * This is useful for checking if flags describing a quantity, such as
- * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
- * To check if the flag -XX:MaxMetaspaceSize is set, use
- * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
- *
- * @param prefix The start of the argument.
- * @return {@code true} if the given argument is the start of an input
- * argument, otherwise {@code false}.
- */
- public static boolean containsPrefix(String prefix) {
- for (String arg : args) {
- if (arg.startsWith(prefix)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the string containing input arguments passed to the VM
- */
- public static String getInputArguments() {
- StringBuilder result = new StringBuilder();
- for (String arg : args)
- result.append(arg).append(' ');
-
- return result.toString();
- }
-
-}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -99,7 +99,7 @@
}
}
if (requestToCurrentProcess) {
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
}
if (jcmdArgs != null) {
for (String toolArg : jcmdArgs) {
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Dec 02 09:34:55 2015 -0800
@@ -27,8 +27,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -253,11 +251,8 @@
*
* @return Process id
*/
- public static int getProcessId() throws Exception {
- RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
- int pid = Integer.parseInt(runtime.getName().split("@")[0]);
-
- return pid;
+ public static long getProcessId() {
+ return ProcessHandle.current().getPid();
}
/**
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -23,9 +23,6 @@
package jdk.testlibrary;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadInfo;
-import java.lang.management.ThreadMXBean;
import java.util.concurrent.TimeoutException;
/**
@@ -204,46 +201,4 @@
}
return null;
}
-
- /**
- * Waits until {@link TestThread} is in the certain {@link State}
- * and blocking on {@code object}.
- *
- * @param state The thread state
- * @param object The object to block on
- */
- public void waitUntilBlockingOnObject(Thread.State state, Object object) {
- String want = object == null ? null : object.getClass().getName() + '@'
- + Integer.toHexString(System.identityHashCode(object));
- ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
- while (isAlive()) {
- ThreadInfo ti = tmx.getThreadInfo(getId());
- if (ti.getThreadState() == state
- && (want == null || want.equals(ti.getLockName()))) {
- return;
- }
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- }
-
- /**
- * Waits until {@link TestThread} is in native.
- */
- public void waitUntilInNative() {
- ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
- while (isAlive()) {
- ThreadInfo ti = tmx.getThreadInfo(getId());
- if (ti.isInNative()) {
- return;
- }
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- }
- }
- }
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/management/InputArguments.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary.management;
+
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+/**
+ * This class provides access to the input arguments to the VM.
+ */
+public class InputArguments {
+ private static final List<String> args;
+
+ static {
+ RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+ args = runtimeMxBean.getInputArguments();
+ }
+
+ /**
+ * Returns true if {@code arg} is an input argument to the VM.
+ *
+ * This is useful for checking boolean flags such as -XX:+UseSerialGC or
+ * -XX:-UsePerfData.
+ *
+ * @param arg The name of the argument.
+ * @return {@code true} if the given argument is an input argument,
+ * otherwise {@code false}.
+ */
+ public static boolean contains(String arg) {
+ return args.contains(arg);
+ }
+
+ /**
+ * Returns true if {@code prefix} is the start of an input argument to the
+ * VM.
+ *
+ * This is useful for checking if flags describing a quantity, such as
+ * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
+ * To check if the flag -XX:MaxMetaspaceSize is set, use
+ * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
+ *
+ * @param prefix The start of the argument.
+ * @return {@code true} if the given argument is the start of an input
+ * argument, otherwise {@code false}.
+ */
+ public static boolean hasArgStartingWith(String prefix) {
+ for (String arg : args) {
+ if (arg.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get the string containing input arguments passed to the VM
+ */
+ public static String getInputArguments() {
+ StringBuilder result = new StringBuilder();
+ for (String arg : args)
+ result.append(arg).append(' ');
+
+ return result.toString();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/management/ThreadMXBeanTool.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary.management;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A few utility methods to use ThreadMXBean.
+ */
+public final class ThreadMXBeanTool {
+
+ /**
+ * Waits until {@link Thread} is in the certain {@link State}
+ * and blocking on {@code object}.
+ *
+ * @param state The thread state
+ * @param object The object to block on
+ */
+ public static void waitUntilBlockingOnObject(Thread thread, Thread.State state, Object object)
+ throws InterruptedException {
+ String want = object == null ? null : object.getClass().getName() + '@'
+ + Integer.toHexString(System.identityHashCode(object));
+ ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+ while (thread.isAlive()) {
+ ThreadInfo ti = tmx.getThreadInfo(thread.getId());
+ if (ti.getThreadState() == state
+ && (want == null || want.equals(ti.getLockName()))) {
+ return;
+ }
+ Thread.sleep(1);
+ }
+ }
+
+ /**
+ * Waits until {@link Thread} is in native.
+ */
+ public static void waitUntilInNative(Thread thread) throws InterruptedException {
+ ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+ while (thread.isAlive()) {
+ ThreadInfo ti = tmx.getThreadInfo(thread.getId());
+ if (ti.isInNative()) {
+ return;
+ }
+ Thread.sleep(1);
+ }
+ }
+
+}
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -21,6 +21,11 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4811482 4700777 4905410
@@ -28,9 +33,6 @@
* HttpsURLConnection; HTTP client: Connect and read timeouts;
* Https needs to support new tiger features that went into http
* @run main/othervm ReadTimeout
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
*/
import java.io.*;
@@ -101,31 +103,32 @@
* Signal Client, we're ready for his connect.
*/
serverReady = true;
- SSLSocket sslSocket = null;
try {
- sslSocket = (SSLSocket) sslServerSocket.accept();
- InputStream sslIS = sslSocket.getInputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(sslIS));
- br.readLine();
- while (!finished()) {
- Thread.sleep (2000);
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ InputStream sslIS = sslSocket.getInputStream();
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(sslIS));
+ br.readLine();
+ while (!finished()) {
+ Thread.sleep(2000);
+ }
}
- sslSocket.close();
reset();
// doing second test
- sslSocket = (SSLSocket) sslServerSocket.accept();
- sslIS = sslSocket.getInputStream();
- br = new BufferedReader(new InputStreamReader(sslIS));
- br.readLine();
- while (!finished()) {
- Thread.sleep (2000);
+ try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+ InputStream sslIS = sslSocket.getInputStream();
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(sslIS));
+ br.readLine();
+ while (!finished()) {
+ Thread.sleep(2000);
+ }
}
- sslSocket.close();
} catch (Exception e) {
+ System.out.println("Should be an expected exception: " + e);
} finally {
- if (sslServerSocket != null)
- sslServerSocket.close();
+ sslServerSocket.close();
}
}
@@ -160,7 +163,7 @@
}
HttpsURLConnection http = null;
try {
- URL url = new URL("https://localhost:"+serverPort);
+ URL url = new URL("https://localhost:" + serverPort);
// set read timeout through system property
System.setProperty("sun.net.client.defaultReadTimeout", "2000");
@@ -168,14 +171,20 @@
new NameVerifier());
http = (HttpsURLConnection)url.openConnection();
- InputStream is = http.getInputStream ();
+ InputStream is = http.getInputStream();
+
+ throw new Exception(
+ "system property timeout configuration does not work");
} catch (SocketTimeoutException stex) {
+ System.out.println("Got expected timeout exception for " +
+ "system property timeout configuration: " + stex);
+ } finally {
done();
http.disconnect();
}
try {
- URL url = new URL("https://localhost:"+serverPort);
+ URL url = new URL("https://localhost:" + serverPort);
HttpsURLConnection.setDefaultHostnameVerifier(
new NameVerifier());
@@ -183,8 +192,14 @@
// set read timeout through API
http.setReadTimeout(2000);
- InputStream is = http.getInputStream ();
+ InputStream is = http.getInputStream();
+
+ throw new Exception(
+ "HttpsURLConnection.setReadTimeout() does not work");
} catch (SocketTimeoutException stex) {
+ System.out.println("Got expected timeout exception for " +
+ "HttpsURLConnection.setReadTimeout(): " + stex);
+ } finally {
done();
http.disconnect();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/mscapi/CastError.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+
+/**
+ * @test
+ * @bug 8143913
+ * @requires os.family == "windows"
+ * @summary MSCAPI keystore should accept Certificate[] in setEntry()
+ */
+
+public class CastError {
+ public static void main(String[] args) throws Exception {
+ KeyStore ks = KeyStore.getInstance(
+ new File(System.getProperty("test.src"),
+ "../tools/jarsigner/JarSigning.keystore"),
+ "bbbbbb".toCharArray());
+
+ PrivateKey pk = (PrivateKey) ks.getKey("c", "bbbbbb".toCharArray());
+ Certificate cert = ks.getCertificate("c");
+
+ ks = KeyStore.getInstance("Windows-MY");
+ ks.load(null, null);
+
+ ks.setKeyEntry("8143913", pk, null, new Certificate[]{cert});
+ ks.deleteEntry("8143913");
+ }
+}
--- a/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/pkcs/pkcs8/PKCS8Test.java Wed Dec 02 09:34:55 2015 -0800
@@ -25,6 +25,7 @@
* @test
* @bug 8048357
* @summary PKCS8 Standards Conformance Tests
+ * @requires (os.family != "solaris")
* @modules java.base/sun.security.pkcs
* java.base/sun.security.util
* java.base/sun.security.provider
@@ -33,6 +34,11 @@
* @compile -XDignore.symbol.file PKCS8Test.java
* @run main PKCS8Test
*/
+
+/*
+ * Skip Solaris since the DSAPrivateKeys returned by
+ * SunPKCS11 Provider are not subclasses of PKCS8Key
+ */
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
@@ -43,7 +49,6 @@
import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.x509.AlgorithmId;
-
import static java.lang.System.out;
public class PKCS8Test {
@@ -191,7 +196,14 @@
public static void main(String[] args)
throws IOException, InvalidKeyException {
- byte[] encodedKey = getEncodedKey();
+ BigInteger p = BigInteger.valueOf(1);
+ BigInteger q = BigInteger.valueOf(2);
+ BigInteger g = BigInteger.valueOf(3);
+ BigInteger x = BigInteger.valueOf(4);
+
+ DSAPrivateKey priv = new DSAPrivateKey(p, q, g, x);
+
+ byte[] encodedKey = priv.getEncoded();
byte[] expectedBytes = new byte[EXPECTED.length];
for (int i = 0; i < EXPECTED.length; i++) {
expectedBytes[i] = (byte) EXPECTED[i];
@@ -203,6 +215,7 @@
}
PKCS8Key decodedKey = PKCS8Key.parse(new DerValue(encodedKey));
+
String alg = decodedKey.getAlgorithm();
AlgorithmId algId = decodedKey.getAlgorithmId();
out.println("Algorithm :" + alg);
@@ -265,30 +278,10 @@
+ EXCEPTION_MESSAGE + " get: " + e.getMessage());
}
}
-
- }
-
- // get a byte array from somewhere
- static byte[] getEncodedKey() throws InvalidKeyException {
- BigInteger p = BigInteger.valueOf(1);
- BigInteger q = BigInteger.valueOf(2);
- BigInteger g = BigInteger.valueOf(3);
- BigInteger x = BigInteger.valueOf(4);
-
- DSAPrivateKey priv = new DSAPrivateKey(p, q, g, x);
- return priv.getEncoded();
}
static void dumpByteArray(String nm, byte[] bytes) throws IOException {
out.println(nm + " length: " + bytes.length);
hexDump.encodeBuffer(bytes, out);
}
-
- static String toString(PKCS8Key key) {
- StringBuilder builder = new StringBuilder(key.getAlgorithm());
- builder.append('\n').append("parameters:")
- .append(key.getAlgorithmId().toString());
- return builder.toString();
- }
-
}
--- a/jdk/test/sun/security/ssl/ExtensionType/OptimalListSize.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/ssl/ExtensionType/OptimalListSize.java Wed Dec 02 09:34:55 2015 -0800
@@ -36,6 +36,6 @@
public static void main(String[] args) throws Throwable {
OptimalCapacity.ofArrayList(
Class.forName("sun.security.ssl.ExtensionType"),
- "knownExtensions", 14);
+ "knownExtensions", 15);
}
}
--- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -52,6 +52,7 @@
+ ".txt";
private static final String PASSWORD = "changeit";
private static final String KEYSTORE = "ks.jks";
+ private static final String CA_KEY_ALIAS = "ca";
private static final String SIGNING_KEY_ALIAS = "sign_alias";
private static final String TSA_KEY_ALIAS = "ts";
private static final String KEY_ALG = "RSA";
@@ -79,20 +80,52 @@
// look for free network port for TSA service
int port = jdk.testlibrary.Utils.getFreePort();
- String host = jdk.testlibrary.Utils.getHostname();
+ String host = "127.0.0.1";
String tsaUrl = "http://" + host + ":" + port;
// create key pair for jar signing
ProcessTools.executeCommand(KEYTOOL,
"-genkey",
+ "-alias", CA_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=CA",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
"-alias", SIGNING_KEY_ALIAS,
"-keyalg", KEY_ALG,
"-keysize", Integer.toString(KEY_SIZE),
"-keystore", KEYSTORE,
"-storepass", PASSWORD,
"-keypass", PASSWORD,
- "-dname", "CN=Test",
- "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+ "-dname", "CN=Test").shouldHaveExitValue(0);
+ ProcessTools.executeCommand(KEYTOOL,
+ "-certreq",
+ "-alias", SIGNING_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-file", "certreq").shouldHaveExitValue(0);
+ ProcessTools.executeCommand(KEYTOOL,
+ "-gencert",
+ "-alias", CA_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-validity", Integer.toString(VALIDITY),
+ "-infile", "certreq",
+ "-outfile", "cert").shouldHaveExitValue(0);
+ ProcessTools.executeCommand(KEYTOOL,
+ "-importcert",
+ "-alias", SIGNING_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-file", "cert").shouldHaveExitValue(0);
// create key pair for TSA service
// SubjectInfoAccess extension contains URL to TSA service
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/Warning.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.JarUtils;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @bug 8024302 8026037 8130132
+ * @summary warnings, errors and -strict
+ * @library /lib/testlibrary
+ */
+public class Warning {
+
+ public static void main(String[] args) throws Throwable {
+
+ Files.deleteIfExists(Paths.get("ks"));
+
+ newCert("ca", "-validity 365000");
+
+ recreateJar();
+
+ newCert("a");
+ run("jarsigner", "a.jar a")
+ .shouldContain("is self-signed");
+ run("jarsigner", "a.jar a -strict")
+ .shouldContain("is self-signed")
+ .shouldHaveExitValue(4);
+ // Trusted entry can be self-signed without a warning
+ run("jarsigner", "-verify a.jar")
+ .shouldNotContain("is self-signed")
+ .shouldNotContain("not signed by alias in this keystore");
+ run("keytool", "-delete -alias a");
+ // otherwise a warning will be shown
+ run("jarsigner", "-verify a.jar")
+ .shouldContain("is self-signed")
+ .shouldContain("not signed by alias in this keystore");
+
+ recreateJar();
+
+ newCert("b");
+ issueCert("b");
+ run("jarsigner", "a.jar b")
+ .shouldNotContain("is self-signed");
+ run("jarsigner", "-verify a.jar")
+ .shouldNotContain("is self-signed");
+
+ run("jarsigner", "a.jar b -digestalg MD5")
+ .shouldContain("-digestalg option is considered a security risk.");
+ run("jarsigner", "a.jar b -digestalg MD5 -strict")
+ .shouldHaveExitValue(4)
+ .shouldContain("-digestalg option is considered a security risk.");
+ run("jarsigner", "a.jar b -sigalg MD5withRSA")
+ .shouldContain("-sigalg option is considered a security risk");
+
+ issueCert("b", "-sigalg MD5withRSA");
+ run("jarsigner", "a.jar b")
+ .shouldMatch("chain is not validated. Reason:.*MD5withRSA");
+
+ recreateJar();
+
+ newCert("c", "-keysize 512");
+ issueCert("c");
+ run("jarsigner", "a.jar c")
+ .shouldContain("chain is not validated. " +
+ "Reason: algorithm constraints check failed");
+
+ recreateJar();
+
+ newCert("s1"); issueCert("s1", "-startdate 2000/01/01 -validity 36525");
+ run("jarsigner", "a.jar s1")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp").shouldContain("2100-01-01")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s1 -strict")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp").shouldContain("2100-01-01")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s1 -verify")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp").shouldContain("2100-01-01")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s1 -verify -strict")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp").shouldContain("2100-01-01")
+ .shouldNotContain("with signer errors");
+
+ recreateJar();
+
+ newCert("s2"); issueCert("s2", "-validity 100");
+ run("jarsigner", "a.jar s2")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp")
+ .shouldContain("will expire")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s2 -strict")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp")
+ .shouldContain("will expire")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s2 -verify")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp")
+ .shouldContain("will expire")
+ .shouldNotContain("with signer errors");
+ run("jarsigner", "a.jar s2 -verify -strict")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("Error:")
+ .shouldContain("timestamp")
+ .shouldContain("will expire")
+ .shouldNotContain("with signer errors");
+
+ recreateJar();
+
+ newCert("s3"); issueCert("s3", "-startdate -200d -validity 100");
+ run("jarsigner", "a.jar s3")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldContain("has expired")
+ .shouldNotContain("with signer errors")
+ .shouldNotContain("Error:");
+ run("jarsigner", "a.jar s3 -strict")
+ .shouldHaveExitValue(4)
+ .shouldContain("with signer errors")
+ .shouldMatch("(?s).*Error:.*has expired.*Warning:.*");
+ run("jarsigner", "a.jar s3 -verify")
+ .shouldHaveExitValue(0)
+ .shouldContain("Warning:")
+ .shouldNotContain("with signer errors")
+ .shouldNotContain("Error:");
+ run("jarsigner", "a.jar s3 -verify -strict")
+ .shouldHaveExitValue(4)
+ .shouldContain("with signer errors")
+ .shouldMatch("(?s).*Error:.*has expired.*Warning:.*");
+ }
+
+ // Creates a new jar without signature
+ static void recreateJar() throws Exception {
+ JarUtils.createJar("a.jar", "ks");
+ }
+
+ // Creates a self-signed cert for alias with zero or more -genkey options
+ static void newCert(String alias, String... more) throws Exception {
+ String args = "-genkeypair -alias " + alias + " -dname CN=" + alias;
+ for (String s: more) {
+ args += " " + s;
+ }
+ run("keytool", args).shouldHaveExitValue(0);
+ }
+
+ // Asks ca to issue a cert to alias with zero or more -gencert options
+ static void issueCert(String alias, String...more) throws Exception {
+ String req = run("keytool", "-certreq -alias " + alias)
+ .shouldHaveExitValue(0).getStdout();
+ String args = "-gencert -alias ca -rfc";
+ for (String s: more) {
+ args += " " + s;
+ }
+ String cert = run("keytool", args, req)
+ .shouldHaveExitValue(0).getStdout();
+ run("keytool", "-import -alias " + alias, cert).shouldHaveExitValue(0);
+ }
+
+ // Runs a java tool with command line arguments
+ static OutputAnalyzer run(String command, String args)
+ throws Exception {
+ return run(command, args, null);
+ }
+
+ // Runs a java tool with command line arguments and an optional input block
+ static OutputAnalyzer run(String command, String args, String input)
+ throws Exception {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(command);
+ launcher.addVMArg("-Duser.language=en").addVMArg("-Duser.country=US");
+ switch (command) {
+ case "keytool":
+ for (String s: new String[] {
+ "-keystore", "ks", "-storepass", "changeit",
+ "-storetype", "jks",
+ "-keypass", "changeit", "-keyalg", "rsa", "-debug"}) {
+ launcher.addToolArg(s);
+ }
+ break;
+ case "jarsigner":
+ for (String s: new String[] {
+ "-keystore", "ks", "-storepass", "changeit",
+ "-storetype", "jks"}) {
+ launcher.addToolArg(s);
+ }
+ break;
+ }
+ for (String arg: args.split(" ")) {
+ launcher.addToolArg(arg);
+ }
+ String[] cmd = launcher.getCommand();
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ OutputAnalyzer out = ProcessTools.executeProcess(pb, input);
+ System.out.println("======================");
+ System.out.println(Arrays.toString(cmd));
+ String msg = " stdout: [" + out.getStdout() + "];\n"
+ + " stderr: [" + out.getStderr() + "]\n"
+ + " exitValue = " + out.getExitValue() + "\n";
+ System.out.println(msg);
+ return out;
+ }
+}
+
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh Wed Dec 02 09:34:55 2015 -0800
@@ -140,19 +140,19 @@
# 16 and 32 already covered in the first part
# ==========================================================
-$KT -genkeypair -alias expired -dname CN=expired -startdate -10m
-$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid -startdate +1m
-$KT -genkeypair -alias badku -dname CN=badku -ext KU=cRLSign -validity 365
-$KT -genkeypair -alias badeku -dname CN=badeku -ext EKU=sa -validity 365
-$KT -genkeypair -alias goodku -dname CN=goodku -ext KU=dig -validity 365
-$KT -genkeypair -alias goodeku -dname CN=goodeku -ext EKU=codesign -validity 365
-
-# badchain signed by ca, but ca is removed later
-$KT -genkeypair -alias badchain -dname CN=badchain -validity 365
$KT -genkeypair -alias ca -dname CN=ca -ext bc -validity 365
-$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \
- $KT -importcert -alias badchain
-$KT -delete -alias ca
+$KT -genkeypair -alias expired -dname CN=expired
+$KT -certreq -alias expired | $KT -gencert -alias ca -startdate -10m | $KT -import -alias expired
+$KT -genkeypair -alias notyetvalid -dname CN=notyetvalid
+$KT -certreq -alias notyetvalid | $KT -gencert -alias ca -startdate +1m | $KT -import -alias notyetvalid
+$KT -genkeypair -alias badku -dname CN=badku
+$KT -certreq -alias badku | $KT -gencert -alias ca -ext KU=cRLSign -validity 365 | $KT -import -alias badku
+$KT -genkeypair -alias badeku -dname CN=badeku
+$KT -certreq -alias badeku | $KT -gencert -alias ca -ext EKU=sa -validity 365 | $KT -import -alias badeku
+$KT -genkeypair -alias goodku -dname CN=goodku
+$KT -certreq -alias goodku | $KT -gencert -alias ca -ext KU=dig -validity 365 | $KT -import -alias goodku
+$KT -genkeypair -alias goodeku -dname CN=goodeku
+$KT -certreq -alias goodeku | $KT -gencert -alias ca -ext EKU=codesign -validity 365 | $KT -import -alias goodeku
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar expired
[ $? = 4 ] || exit $LINENO
@@ -172,6 +172,12 @@
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar goodeku
[ $? = 0 ] || exit $LINENO
+# badchain signed by ca, but ca is removed later
+$KT -genkeypair -alias badchain -dname CN=badchain -validity 365
+$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \
+ $KT -importcert -alias badchain
+$KT -delete -alias ca
+
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar badchain
[ $? = 4 ] || exit $LINENO
@@ -182,18 +188,22 @@
# Third part: -certchain test
# ==========================================================
-# altchain signed by ca2, but ca2 is removed later
+# altchain signed by ca2
$KT -genkeypair -alias altchain -dname CN=altchain -validity 365
$KT -genkeypair -alias ca2 -dname CN=ca2 -ext bc -validity 365
$KT -certreq -alias altchain | $KT -gencert -alias ca2 -validity 365 -rfc > certchain
$KT -exportcert -alias ca2 -rfc >> certchain
-$KT -delete -alias ca2
-# Now altchain is still self-signed
+# Self-signed cert does not work
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar altchain
+[ $? = 4 ] || exit $LINENO
+
+# -certchain works
+$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
[ $? = 0 ] || exit $LINENO
-# If -certchain is used, then it's bad
+# but if ca2 is removed, -certchain does not work
+$KT -delete -alias ca2
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
[ $? = 4 ] || exit $LINENO
--- a/jdk/test/sun/security/tools/jarsigner/default_options.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/default_options.sh Wed Dec 02 09:34:55 2015 -0800
@@ -31,19 +31,21 @@
TESTJAVA=`dirname $JAVAC_CMD`/..
fi
+PASS=changeit
+export PASS
+
KS=ks
-KEYTOOL="$TESTJAVA/bin/keytool ${TESTTOOLVMOPTS}"
+KEYTOOL="$TESTJAVA/bin/keytool ${TESTTOOLVMOPTS} -storepass:env PASS -keypass:env PASS -keystore $KS"
JAR="$TESTJAVA/bin/jar ${TESTTOOLVMOPTS}"
JARSIGNER="$TESTJAVA/bin/jarsigner ${TESTTOOLVMOPTS}"
rm $KS 2> /dev/null
-PASS=changeit
-export PASS
-
-$KEYTOOL -genkeypair -dname CN=A -alias a \
- -storepass:env PASS -keypass:env PASS -keystore $KS \
- -keyalg rsa || exit 1
+$KEYTOOL -genkeypair -dname CN=A -alias a -keyalg rsa || exit 1
+$KEYTOOL -genkeypair -dname CN=CA -alias ca -keyalg rsa || exit 2
+$KEYTOOL -alias a -certreq |
+ $KEYTOOL -alias ca -gencert |
+ $KEYTOOL -alias a -import || exit 3
cat <<EOF > js.conf
jarsigner.all = -keystore \${user.dir}/$KS -storepass:env PASS -debug -strict
--- a/jdk/test/sun/security/tools/jarsigner/ec.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/ec.sh Wed Dec 02 09:34:55 2015 -0800
@@ -53,11 +53,20 @@
echo A > A
$JAR cvf $JFILE A
-$KT -alias a -dname CN=a -keyalg ec -genkey -validity 300 || exit 11
-$KT -alias b -dname CN=b -keyalg ec -genkey -validity 300 || exit 12
+$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11
+
+$KT -alias a -dname CN=a -keyalg ec -genkey || exit 11
+$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111
+
+$KT -alias b -dname CN=b -keyalg ec -genkey || exit 12
+$KT -alias b -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias b || exit 121
+
# Ensure that key length is sufficient for the intended hash (SHA512withECDSA)
-$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 -keysize 521 || exit 13
+$KT -alias c -dname CN=c -keyalg ec -genkey -keysize 521 || exit 13
+$KT -alias c -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias c || exit 131
+
$KT -alias x -dname CN=x -keyalg ec -genkey -validity 300 || exit 14
+$KT -alias x -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias x || exit 141
$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 21
$JARSIGNER -keystore $KS -storepass changeit $JFILE b -debug -strict -sigalg SHA1withECDSA || exit 22
--- a/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/onlymanifest.sh Wed Dec 02 09:34:55 2015 -0800
@@ -57,12 +57,14 @@
echo "Key: Value" > manifest
$JAR cvfm $JFILE manifest
-$KT -alias a -dname CN=a -genkey -validity 300 || exit 1
-$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 2
+$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1
+$KT -alias a -dname CN=a -genkey -validity 300 || exit 2
+$KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3
+$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4
$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE a -debug -strict \
- > onlymanifest.out || exit 3
+ > onlymanifest.out || exit 5
-grep unsigned onlymanifest.out && exit 4
+grep unsigned onlymanifest.out && exit 6
exit 0
--- a/jdk/test/sun/security/tools/jarsigner/ts.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/ts.sh Wed Dec 02 09:34:55 2015 -0800
@@ -73,6 +73,10 @@
$KT -alias tsbad1 -genkeypair -dname CN=tsbad1
$KT -alias tsbad2 -genkeypair -dname CN=tsbad2
$KT -alias tsbad3 -genkeypair -dname CN=tsbad3
+
+$KT -alias old -certreq | \
+ $KT -alias ca -gencert | \
+ $KT -alias old -importcert
$KT -alias ts -certreq | \
$KT -alias ca -gencert -ext eku:critical=ts | \
$KT -alias ts -importcert
--- a/jdk/test/sun/security/tools/jarsigner/warning.sh Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-#
-# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
-# 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 8024302
-# @bug 8026037
-# @summary Clarify jar verifications
-#
-
-if [ "${TESTJAVA}" = "" ] ; then
- JAVAC_CMD=`which javac`
- TESTJAVA=`dirname $JAVAC_CMD`/..
-fi
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- Windows_* )
- FS="\\"
- ;;
- * )
- FS="/"
- ;;
-esac
-
-KS=warnings.jks
-JFILE=warnings.jar
-
-KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit \
- -keystore $KS"
-JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
-JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -keystore $KS -storepass changeit"
-
-rm $KS 2> /dev/null
-
-LANG=C
-export LANG
-
-echo 12345 > file
-
-ERR=""
-
-# Normal signer expiring on 2100-01-01
-$KT -alias s1 -dname CN=s1 -genkey -startdate 2000/01/01 -validity 36525 || ERR="$ERR keytool s1,"
-# Cert expiring soon, informational warning
-$KT -alias s2 -dname CN=s2 -genkey -validity 100 || ERR="$ERR keytool s2,"
-# Cert expired, severe warning
-$KT -alias s3 -dname CN=s3 -genkey -startdate -200d -validity 100 || ERR="$ERR keytool s3,"
-
-# noTimestamp is informatiional warning and includes a date
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s1 > output1 || ERR="$ERR jarsigner s1,"
-$JARSIGNER -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
-$JARSIGNER -verify $JFILE s1 >> output1 || ERR="$ERR jarsigner s1,"
-$JARSIGNER -verify -strict $JFILE s1 >> output1 || ERR="$ERR jarsigner s1 strict,"
-
-cat output1 | grep Warning || ERR="$ERR s1 warning,"
-cat output1 | grep Error && ERR="$ERR s1 error,"
-cat output1 | grep timestamp | grep 2100-01-01 || ERR="$ERR s1 timestamp,"
-cat output1 | grep "with signer errors" && ERR="$ERR s1 err,"
-
-# hasExpiringCert is informatiional warning
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s2 > output2 || ERR="$ERR jarsigner s2,"
-$JARSIGNER -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
-$JARSIGNER -verify $JFILE s2 >> output2 || ERR="$ERR jarsigner s2,"
-$JARSIGNER -verify -strict $JFILE s2 >> output2 || ERR="$ERR jarsigner s2 strict,"
-
-cat output2 | grep Warning || ERR="$ERR s2 warning,"
-cat output2 | grep Error && ERR="$ERR s2 error,"
-cat output2 | grep timestamp || ERR="$ERR s2 timestamp,"
-cat output2 | grep "will expire" || ERR="$ERR s2 expiring,"
-cat output2 | grep "with signer errors" && ERR="$ERR s2 err,"
-
-# hasExpiredCert is severe warning
-$JAR cvf $JFILE file
-$JARSIGNER $JFILE s3 > output3 || ERR="$ERR jarsigner s3,"
-$JARSIGNER -strict $JFILE s3 > output3s && ERR="$ERR jarsigner s3 strict,"
-$JARSIGNER -verify $JFILE s3 >> output3 || ERR="$ERR jarsigner s3,"
-$JARSIGNER -verify -strict $JFILE s3 >> output3s && ERR="$ERR jarsigner s3 strict,"
-
-# warning without -strict
-cat output3 | grep Warning || ERR="$ERR s3 warning,"
-cat output3 | grep Error && ERR="$ERR s3 error,"
-cat output3 | grep "with signer errors" && ERR="$ERR s3 err,"
-
-# error with -strict
-cat output3s | grep Warning || ERR="$ERR s3s warning,"
-cat output3s | grep Error || ERR="$ERR s3s error,"
-cat output3s | grep "with signer errors" || ERR="$ERR s3 err,"
-
-if [ "$ERR" = "" ]; then
- exit 0
-else
- echo "ERR is $ERR"
- exit 1
-fi
--- a/jdk/test/sun/security/tools/jarsigner/weaksize.sh Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/security/tools/jarsigner/weaksize.sh Wed Dec 02 09:34:55 2015 -0800
@@ -52,9 +52,9 @@
$JAR cvf a.jar ks
# We always trust a TrustedCertificateEntry
-$JS a.jar ca || exit 1
+$JS a.jar ca | grep "chain is not validated" && exit 1
# An end-entity cert must follow algorithm constraints
-$JS a.jar signer && exit 2
+$JS a.jar signer | grep "chain is not validated" || exit 2
exit 0
--- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Wed Dec 02 09:34:55 2015 -0800
@@ -71,7 +71,7 @@
output.shouldHaveExitValue(0);
output.shouldNotContain("Exception");
- output.shouldContain(Integer.toString(ProcessTools.getProcessId()) + ":");
+ output.shouldContain(Long.toString(ProcessTools.getProcessId()) + ":");
matchJcmdCommands(output);
output.shouldContain("For more information about a specific command use 'help <command>'.");
}
--- a/jdk/test/sun/tools/jinfo/JInfoHelper.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/tools/jinfo/JInfoHelper.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
}
}
if (toPid) {
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
}
ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
--- a/jdk/test/sun/tools/jmap/BasicJMapTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/tools/jmap/BasicJMapTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -42,9 +42,9 @@
* @modules java.management
* @build jdk.testlibrary.*
* @build jdk.test.lib.hprof.*
- * @build jdk.test.lib.hprof.module.*
+ * @build jdk.test.lib.hprof.model.*
* @build jdk.test.lib.hprof.parser.*
- * @build jdk.test.lib.hprof.utils.*
+ * @build jdk.test.lib.hprof.util.*
* @run main/timeout=240 BasicJMapTest
*/
public class BasicJMapTest {
@@ -111,7 +111,7 @@
launcher.addToolArg(toolArg);
}
}
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
--- a/jdk/test/sun/tools/jps/JpsBase.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/tools/jps/JpsBase.java Wed Dec 02 09:34:55 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
}
public static void main(String[] args) throws Exception {
- int pid = ProcessTools.getProcessId();
+ long pid = ProcessTools.getProcessId();
List<List<JpsHelper.JpsArg>> combinations = JpsHelper.JpsArg.generateCombinations();
for (List<JpsHelper.JpsArg> combination : combinations) {
@@ -76,7 +76,7 @@
// 30673
isQuiet = true;
JpsHelper.verifyJpsOutput(output, "^\\d+$");
- output.shouldContain(Integer.toString(pid));
+ output.shouldContain(Long.toString(pid));
break;
case l:
// If '-l' is specified output should contain the full package name for the application's main class
--- a/jdk/test/sun/tools/jstack/BasicJStackTest.java Wed Jul 05 21:04:26 2017 +0200
+++ b/jdk/test/sun/tools/jstack/BasicJStackTest.java Wed Dec 02 09:34:55 2015 -0800
@@ -63,7 +63,7 @@
launcher.addToolArg(toolArg);
}
}
- launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+ launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/MultiRelease.java Wed Dec 02 09:34:55 2015 -0800
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ r You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8066272
+ * @summary tests a simple multi-versioned jar file
+ * @compile -XDignore.symbol.file Utils.java MultiRelease.java
+ * @run main MultiRelease
+ * @author ksrini
+ */
+
+public class MultiRelease {
+ private static final File cwd = new File(".");
+ private static int pass = 0;
+ private static int fail = 0;
+ // specify alternate name via arguments to verify
+ // if permanent fix works
+
+ private static final String PropKey = "pack200.MultiRelease.META-INF";
+ private static final String MetaInfName = System.getProperty(PropKey, "META-INF");
+
+ public static void main(String... args) throws Exception {
+ new MultiRelease().run();
+ }
+
+ void run() throws Exception {
+ List<TestCase> testCases = new ArrayList<>();
+ testCases.add(new TestCase1());
+ testCases.add(new TestCase2());
+ for (TestCase tc : testCases) {
+ tc.run();
+ }
+ if (fail > 0) {
+ throw new Exception(fail + "/" + testCases.size() + " tests fails");
+ } else {
+ System.out.println("All tests(" + pass + ") passes");
+ }
+ }
+
+ /*
+ * An abstract class to eliminate test boiler plating.
+ */
+ static abstract class TestCase {
+ final File tcwd;
+ final File metaInfDir;
+ final File versionsDir;
+ final File manifestFile;
+
+ TestCase(String directory) throws IOException {
+ System.out.println("initializing directories");
+ tcwd = new File(cwd, directory);
+ metaInfDir = mkdir(new File(tcwd, MetaInfName));
+ versionsDir = mkdir(new File(metaInfDir, "versions"));
+ manifestFile = new File(tcwd, "manifest.tmp");
+ List<String> scratch = new ArrayList<>();
+ scratch.add("Multi-Release: true");
+ Utils.createFile(manifestFile, scratch);
+ }
+
+ File mkdir(File f) throws IOException {
+ if (f.exists() && f.isDirectory() && f.canRead() && f.canWrite()) {
+ return f;
+ }
+ if (!f.mkdirs()) {
+ throw new IOException("mkdirs failed: " + f.getAbsolutePath());
+ }
+ return f;
+ }
+
+ abstract void emitClassFiles() throws Exception;
+
+ void run() {
+ try {
+ emitClassFiles();
+ // jar the file up
+ File testFile = new File(tcwd, "test" + Utils.JAR_FILE_EXT);
+ Utils.jar("cvfm",
+ testFile.getAbsolutePath(),
+ manifestFile.getAbsolutePath(),
+ "-C",
+ tcwd.getAbsolutePath(),
+ ".");
+ File outFile = new File(tcwd, "test-repacked" + Utils.JAR_FILE_EXT);
+ List<String> cmdsList = new ArrayList<>();
+
+ cmdsList.add(Utils.getPack200Cmd());
+ cmdsList.add("-J-ea");
+ cmdsList.add("-J-esa");
+ cmdsList.add("-v");
+ cmdsList.add("--repack");
+ cmdsList.add(outFile.getAbsolutePath());
+ cmdsList.add(testFile.getAbsolutePath());
+ List<String> output = Utils.runExec(cmdsList);
+ Utils.doCompareVerify(testFile.getAbsoluteFile(), outFile.getAbsoluteFile());
+ pass++;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ fail++;
+ }
+ }
+ }
+
+ static class TestCase1 extends TestCase {
+ private TestCase1(String directory) throws IOException {
+ super(directory);
+ }
+
+ public TestCase1() throws Exception {
+ this("case1");
+ }
+
+ @Override
+ void emitClassFiles() throws Exception {
+ emitClassFile("");
+ emitClassFile("7");
+ emitClassFile("8");
+ emitClassFile("9");
+ }
+
+ /*
+ * Adds different variants of types
+ */
+ void emitClassFile(String version) throws IOException {
+ final File outDir = mkdir(version.isEmpty()
+ ? tcwd
+ : new File(versionsDir, version));
+
+ final File srcDir = mkdir(version.isEmpty()
+ ? new File(tcwd, "src")
+ : new File(new File(versionsDir, version), "src"));
+
+ final String fname = "Foo";
+ final File srcFile = new File(srcDir, fname + Utils.JAVA_FILE_EXT);
+ List<String> scratch = new ArrayList<>();
+
+ scratch.add("package pkg;");
+ switch (version) {
+ case "7":
+ scratch.add("public class Foo {");
+ scratch.add("public static final class Bar {}");
+ break;
+ case "8":
+ scratch.add("public abstract class Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ case "9":
+ scratch.add("public interface Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ default:
+ scratch.add("public class Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ }
+ scratch.add("}");
+
+ Utils.createFile(srcFile, scratch);
+ Utils.compiler("-d",
+ outDir.getAbsolutePath(),
+ srcFile.getAbsolutePath());
+ }
+ }
+
+ static class TestCase2 extends TestCase {
+ private TestCase2(String directory) throws IOException {
+ super(directory);
+ }
+
+ TestCase2() throws Exception {
+ this("case2");
+ }
+
+ @Override
+ void emitClassFiles() throws Exception {
+ emitClassFile("");
+ emitClassFile("8");
+ }
+
+ /*
+ * Adds different variants of types and tries to invoke an
+ * interface or concrete method defined by them.
+ */
+ void emitClassFile(String version) throws IOException {
+
+ final File outDir = mkdir(version.isEmpty()
+ ? tcwd
+ : new File(versionsDir, version));
+
+ final File srcDir = mkdir(version.isEmpty()
+ ? new File(tcwd, "src")
+ : new File(new File(versionsDir, version), "src"));
+
+ List<String> scratch = new ArrayList<>();
+ final String fname1 = "Ab";
+ final File srcFile1 = new File(srcDir, fname1 + Utils.JAVA_FILE_EXT);
+
+ final String fname2 = "AbNormal";
+ final File srcFile2 = new File(srcDir, fname2 + Utils.JAVA_FILE_EXT);
+ switch (version) {
+ case "8":
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public interface " + fname1 + "{");
+ scratch.add(" public abstract void close() throws IOException ;");
+ scratch.add("}");
+ Utils.createFile(srcFile1, scratch);
+ break;
+ default:
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public abstract class " + fname1 + "{");
+ scratch.add(" public abstract void close() throws IOException ;");
+ scratch.add("}");
+ Utils.createFile(srcFile1, scratch);
+ }
+
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public class " + fname2 + "{");
+ scratch.add(" public void doSomething(Ab ab) throws IOException {");
+ scratch.add(" ab.close();");
+ scratch.add(" }");
+ scratch.add("}");
+
+ Utils.createFile(srcFile2, scratch);
+ Utils.compiler("-d",
+ outDir.getAbsolutePath(),
+ srcFile1.getAbsolutePath(),
+ srcFile2.getAbsolutePath());
+ }
+ }
+}