# HG changeset patch
# User jwilhelm
# Date 1478879076 -3600
# Node ID 95af45781076898add1fbb5a6af12dec97ae18ca
# Parent f71b844f33d1c25b65775c26b048157052cca69b# Parent 31f5023200d42185b70c4c00ba5672391e4642d0
Merge
diff -r f71b844f33d1 -r 95af45781076 .hgtags
--- a/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -384,3 +384,5 @@
65477538bec32963dc41153d89c4417eb46c45fc jdk-9+139
0875007901f7d364a08220b052f0c81003e9c8c5 jdk-9+140
9aadd2163b568d76f8969ad2fb404a63733da359 jdk-9+141
+df0e03e3ca0ed1307793017dfc1a054c8726131c jdk-9+142
+d62173b931bf5b6bffc6e80a9060bb2e8b8efc75 jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 .hgtags-top-repo
--- a/.hgtags-top-repo Mon Nov 14 11:15:43 2016 +0100
+++ b/.hgtags-top-repo Fri Nov 11 16:44:36 2016 +0100
@@ -384,3 +384,5 @@
7dcf453eacae79ee86a6bcc75fd0b546fc99b48a jdk-9+139
a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
f64afae7f1a5608e438585bbf0bc23785e69cba0 jdk-9+141
+2b3e5caafe3594ea507c37675c4d3086f415dc64 jdk-9+142
+1fc62b1c629fb80fdaa639d3b59452a184f0d705 jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 common/autoconf/flags.m4
--- a/common/autoconf/flags.m4 Mon Nov 14 11:15:43 2016 +0100
+++ b/common/autoconf/flags.m4 Fri Nov 11 16:44:36 2016 +0100
@@ -280,7 +280,7 @@
else
# Default works for linux, might work on other platforms as well.
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1'
@@ -305,7 +305,7 @@
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1'
@@ -315,7 +315,7 @@
C_FLAG_REORDER='-xF'
CXX_FLAG_REORDER='-xF'
SHARED_LIBRARY_FLAGS="-G"
- SET_EXECUTABLE_ORIGIN='-R\$$$$ORIGIN[$]1'
+ SET_EXECUTABLE_ORIGIN='-R\$$ORIGIN[$]1'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-h [$]1'
SET_SHARED_LIBRARY_MAPFILE='-M[$]1'
@@ -759,6 +759,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
$2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
$2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
@@ -940,6 +944,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_$1_CPU" = xs390x; then
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
@@ -999,6 +1007,7 @@
# Setup some hard coded includes
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
+ -I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \
diff -r f71b844f33d1 -r 95af45781076 common/autoconf/generated-configure.sh
--- a/common/autoconf/generated-configure.sh Mon Nov 14 11:15:43 2016 +0100
+++ b/common/autoconf/generated-configure.sh Fri Nov 11 16:44:36 2016 +0100
@@ -5093,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1477108079
+DATE_WHEN_GENERATED=1478524503
###############################################################################
#
@@ -49070,7 +49070,7 @@
else
# Default works for linux, might work on other platforms as well.
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=$1'
@@ -49095,7 +49095,7 @@
# Default works for linux, might work on other platforms as well.
PICFLAG='-fPIC'
SHARED_LIBRARY_FLAGS='-shared'
- SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Wl,-soname=$1'
SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=$1'
@@ -49105,7 +49105,7 @@
C_FLAG_REORDER='-xF'
CXX_FLAG_REORDER='-xF'
SHARED_LIBRARY_FLAGS="-G"
- SET_EXECUTABLE_ORIGIN='-R\$$$$ORIGIN$1'
+ SET_EXECUTABLE_ORIGIN='-R\$$ORIGIN$1'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-h $1'
SET_SHARED_LIBRARY_MAPFILE='-M$1'
@@ -49840,6 +49840,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
@@ -50122,6 +50126,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
JVM_CFLAGS="$JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_TARGET_CPU" = xs390x; then
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
@@ -50270,6 +50278,7 @@
# Setup some hard coded includes
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
+ -I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
@@ -50655,6 +50664,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
@@ -50937,6 +50950,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_BUILD_CPU" = xs390x; then
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
@@ -51085,6 +51102,7 @@
# Setup some hard coded includes
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
+ -I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \
diff -r f71b844f33d1 -r 95af45781076 common/autoconf/spec.gmk.in
--- a/common/autoconf/spec.gmk.in Mon Nov 14 11:15:43 2016 +0100
+++ b/common/autoconf/spec.gmk.in Fri Nov 11 16:44:36 2016 +0100
@@ -265,6 +265,10 @@
BUNDLES_OUTPUTDIR=$(BUILD_OUTPUT)/bundles
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
+
+# By default, output javadoc directly into image
+JAVADOC_OUTPUTDIR = $(DOCS_IMAGE_DIR)
+
# This does not get overridden in a bootcycle build
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
@@ -784,11 +788,12 @@
SYMBOLS_IMAGE_DIR=$(IMAGES_OUTPUTDIR)/$(SYMBOLS_IMAGE_SUBDIR)
# Interim image
+INTERIM_JMODS_DIR := $(SUPPORT_OUTPUTDIR)/interim-jmods
INTERIM_IMAGE_DIR := $(SUPPORT_OUTPUTDIR)/interim-image
# Docs image
DOCS_IMAGE_SUBDIR := docs
-DOCS_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(DOCS_IMAGE_SUBDIR)
+DOCS_IMAGE_DIR = $(IMAGES_OUTPUTDIR)/$(DOCS_IMAGE_SUBDIR)
# Macosx bundles directory definitions
JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle
diff -r f71b844f33d1 -r 95af45781076 corba/.hgtags
--- a/corba/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/corba/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -384,3 +384,5 @@
8c9da7fc5b07c606afd571c7012441b77dda83b2 jdk-9+139
9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
b32f998da32b488ec7c4e9dbb3c750841b48e74d jdk-9+141
+408c9c621938ca028e20bced0459f815de47eba8 jdk-9+142
+6211236ef15ec796806357608b1dd1b70c258ece jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 hotspot/.hgtags
--- a/hotspot/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -544,3 +544,5 @@
08492e67bf3226784dab3bf9ae967382ddbc1af5 jdk-9+139
fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
160a00bc6ed0af1fdf8418fc65e6bddbbc0c536d jdk-9+141
+7b48d63dfd6b8e2657288de3d7b1f153dee02d7e jdk-9+142
+d87d5d430c42342f0320ca7f5cbe0cbd1f9d62ba jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 hotspot/make/gensrc/GensrcJvmti.gmk
--- a/hotspot/make/gensrc/GensrcJvmti.gmk Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/make/gensrc/GensrcJvmti.gmk Fri Nov 11 16:44:36 2016 +0100
@@ -135,14 +135,14 @@
# Copy jvmti.h to include dir
# The file is the same regardless of jvm variant. Only let one do the copy.
-#ifeq ($(JVM_VARIANT), $(firstword $(JVM_VARIANTS)))
-# $(eval $(call SetupCopyFiles, COPY_JVMTI_H, \
-# DEST := $(SUPPORT_OUTPUTDIR)/modules_include/java.base, \
-# FILES := $(JVMTI_OUTPUTDIR)/jvmti.h, \
-# ))
+ifeq ($(JVM_VARIANT), $(firstword $(JVM_VARIANTS)))
+ $(eval $(call SetupCopyFiles, COPY_JVMTI_H, \
+ DEST := $(SUPPORT_OUTPUTDIR)/modules_include/java.base, \
+ FILES := $(JVMTI_OUTPUTDIR)/jvmti.h, \
+ ))
-# TARGETS += $(COPY_JVMTI_H)
-#endif
+ TARGETS += $(COPY_JVMTI_H)
+endif
################################################################################
# Create trace files in gensrc/tracefiles
diff -r f71b844f33d1 -r 95af45781076 hotspot/make/symbols/symbols-unix
--- a/hotspot/make/symbols/symbols-unix Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/make/symbols/symbols-unix Fri Nov 11 16:44:36 2016 +0100
@@ -125,7 +125,6 @@
JVM_GetProtectionDomain
JVM_GetSimpleBinaryName
JVM_GetStackAccessControlContext
-JVM_GetStackTraceElements
JVM_GetSystemPackage
JVM_GetSystemPackages
JVM_GetTemporaryDirectory
@@ -135,6 +134,8 @@
JVM_HoldsLock
JVM_IHashCode
JVM_InitProperties
+JVM_InitStackTraceElement
+JVM_InitStackTraceElementArray
JVM_InternString
JVM_Interrupt
JVM_InvokeMethod
@@ -178,7 +179,6 @@
JVM_StopThread
JVM_SupportsCX8
JVM_SuspendThread
-JVM_ToStackTraceElement
JVM_TotalMemory
JVM_UnloadLibrary
JVM_WaitForReferencePendingList
diff -r f71b844f33d1 -r 95af45781076 hotspot/src/share/vm/classfile/javaClasses.cpp
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Nov 11 16:44:36 2016 +0100
@@ -2175,6 +2175,14 @@
const char* str = holder->external_name();
oop classname = StringTable::intern((char*) str, CHECK);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
+ java_lang_StackTraceElement::set_declaringClassObject(element(), holder->java_mirror());
+
+ oop loader = holder->class_loader();
+ if (loader != NULL) {
+ oop loader_name = java_lang_ClassLoader::name(loader);
+ if (loader_name != NULL)
+ java_lang_StackTraceElement::set_classLoaderName(element(), loader_name);
+ }
// The method can be NULL if the requested class version is gone
Symbol* sym = !method.is_null() ? method->name() : holder->constants()->symbol_at(cpref);
@@ -3433,6 +3441,7 @@
bool java_lang_ClassLoader::offsets_computed = false;
int java_lang_ClassLoader::_loader_data_offset = -1;
int java_lang_ClassLoader::parallelCapable_offset = -1;
+int java_lang_ClassLoader::name_offset = -1;
int java_lang_ClassLoader::unnamedModule_offset = -1;
ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
@@ -3453,6 +3462,9 @@
compute_optional_offset(parallelCapable_offset,
k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature());
+ compute_offset(name_offset,
+ k1, vmSymbols::name_name(), vmSymbols::string_signature());
+
compute_offset(unnamedModule_offset,
k1, vmSymbols::unnamedModule_name(), vmSymbols::module_signature());
@@ -3464,6 +3476,11 @@
return loader->obj_field(parent_offset);
}
+oop java_lang_ClassLoader::name(oop loader) {
+ assert(is_instance(loader), "loader must be oop");
+ return loader->obj_field(name_offset);
+}
+
bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
assert(is_instance(loader), "loader must be oop");
assert(cl == NULL || is_instance(cl), "cl argument must be oop");
@@ -3619,12 +3636,14 @@
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
int java_lang_System::static_security_offset;
-int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
int java_lang_StackTraceElement::lineNumber_offset;
int java_lang_StackTraceElement::moduleName_offset;
int java_lang_StackTraceElement::moduleVersion_offset;
+int java_lang_StackTraceElement::classLoaderName_offset;
+int java_lang_StackTraceElement::declaringClass_offset;
+int java_lang_StackTraceElement::classOrLoaderModuleClassName_offset;
int java_lang_StackFrameInfo::_declaringClass_offset;
int java_lang_StackFrameInfo::_memberName_offset;
int java_lang_StackFrameInfo::_bci_offset;
@@ -3669,6 +3688,14 @@
element->obj_field_put(moduleVersion_offset, value);
}
+void java_lang_StackTraceElement::set_classLoaderName(oop element, oop value) {
+ element->obj_field_put(classLoaderName_offset, value);
+}
+
+void java_lang_StackTraceElement::set_declaringClassObject(oop element, oop value) {
+ element->obj_field_put(classOrLoaderModuleClassName_offset, value);
+}
+
// Support for java_lang_StackFrameInfo
void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
element->obj_field_put(_declaringClass_offset, value);
@@ -3784,6 +3811,8 @@
java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x;
// java_lang_StackTraceElement
+ java_lang_StackTraceElement::classOrLoaderModuleClassName_offset= java_lang_StackTraceElement::hc_classOrLoaderModuleClassName_offset* x + header;
+ java_lang_StackTraceElement::classLoaderName_offset = java_lang_StackTraceElement::hc_classLoaderName_offset * x + header;
java_lang_StackTraceElement::moduleName_offset = java_lang_StackTraceElement::hc_moduleName_offset * x + header;
java_lang_StackTraceElement::moduleVersion_offset = java_lang_StackTraceElement::hc_moduleVersion_offset * x + header;
java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header;
@@ -3985,10 +4014,14 @@
// java.lang.StackTraceElement
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;");
- CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, classOrLoaderModuleClassName, "Ljava/lang/Object;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, classLoaderName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, moduleName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, moduleVersion, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;");
+ CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I");
// java.lang.ref.Reference
diff -r f71b844f33d1 -r 95af45781076 hotspot/src/share/vm/classfile/javaClasses.hpp
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Fri Nov 11 16:44:36 2016 +0100
@@ -1225,6 +1225,7 @@
static bool offsets_computed;
static int parent_offset;
static int parallelCapable_offset;
+ static int name_offset;
static int unnamedModule_offset;
public:
@@ -1234,6 +1235,7 @@
static ClassLoaderData* loader_data(oop loader);
static oop parent(oop loader);
+ static oop name(oop loader);
static bool isAncestor(oop loader, oop cl);
// Support for parallelCapable field
@@ -1291,14 +1293,18 @@
class java_lang_StackTraceElement: AllStatic {
private:
enum {
- hc_moduleName_offset = 0,
- hc_moduleVersion_offset = 1,
- hc_declaringClass_offset = 2,
- hc_methodName_offset = 3,
- hc_fileName_offset = 4,
- hc_lineNumber_offset = 5
+ hc_classOrLoaderModuleClassName_offset = 0,
+ hc_classLoaderName_offset = 1,
+ hc_moduleName_offset = 2,
+ hc_moduleVersion_offset = 3,
+ hc_declaringClass_offset = 4,
+ hc_methodName_offset = 5,
+ hc_fileName_offset = 6,
+ hc_lineNumber_offset = 7
};
+ static int classOrLoaderModuleClassName_offset;
+ static int classLoaderName_offset;
static int moduleName_offset;
static int moduleVersion_offset;
static int declaringClass_offset;
@@ -1307,12 +1313,14 @@
static int lineNumber_offset;
// Setters
+ static void set_classLoaderName(oop element, oop value);
static void set_moduleName(oop element, oop value);
static void set_moduleVersion(oop element, oop value);
static void set_declaringClass(oop element, oop value);
static void set_methodName(oop element, oop value);
static void set_fileName(oop element, oop value);
static void set_lineNumber(oop element, int value);
+ static void set_declaringClassObject(oop element, oop value);
public:
// Create an instance of StackTraceElement
diff -r f71b844f33d1 -r 95af45781076 hotspot/src/share/vm/prims/jvm.cpp
--- a/hotspot/src/share/vm/prims/jvm.cpp Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Nov 11 16:44:36 2016 +0100
@@ -503,16 +503,27 @@
JVM_END
-JVM_ENTRY(void, JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray stackTrace))
- JVMWrapper("JVM_GetStackTraceElements");
+// java.lang.StackTraceElement //////////////////////////////////////////////
+
+
+JVM_ENTRY(void, JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable))
+ JVMWrapper("JVM_InitStackTraceElementArray");
Handle exception(THREAD, JNIHandles::resolve(throwable));
- objArrayOop st = objArrayOop(JNIHandles::resolve(stackTrace));
+ objArrayOop st = objArrayOop(JNIHandles::resolve(elements));
objArrayHandle stack_trace(THREAD, st);
// Fill in the allocated stack trace
java_lang_Throwable::get_stack_trace_elements(exception, stack_trace, CHECK);
JVM_END
+JVM_ENTRY(void, JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo))
+ JVMWrapper("JVM_InitStackTraceElement");
+ Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(stackFrameInfo));
+ Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(element));
+ java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
+JVM_END
+
+
// java.lang.StackWalker //////////////////////////////////////////////////////
@@ -566,13 +577,6 @@
start_index, frames_array_h, THREAD);
JVM_END
-JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
- JVMWrapper("JVM_ToStackTraceElement");
- Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
- Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
- java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
-JVM_END
-
// java.lang.Object ///////////////////////////////////////////////
diff -r f71b844f33d1 -r 95af45781076 hotspot/src/share/vm/prims/jvm.h
--- a/hotspot/src/share/vm/prims/jvm.h Mon Nov 14 11:15:43 2016 +0100
+++ b/hotspot/src/share/vm/prims/jvm.h Fri Nov 11 16:44:36 2016 +0100
@@ -189,8 +189,14 @@
JNIEXPORT void JNICALL
JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
+/*
+ * java.lang.StackTraceElement
+ */
JNIEXPORT void JNICALL
-JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements);
+JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable);
+
+JNIEXPORT void JNICALL
+JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo);
/*
* java.lang.StackWalker
@@ -212,9 +218,6 @@
jint frame_count, jint start_index,
jobjectArray frames);
-JNIEXPORT void JNICALL
-JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
-
/*
* java.lang.Thread
*/
diff -r f71b844f33d1 -r 95af45781076 jaxp/.hgtags
--- a/jaxp/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -384,3 +384,5 @@
8991d71c5316bde259e6a417c1199b008ca3cdf0 jdk-9+139
8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
037c095ba0c345edbeaaab52fda913a76c3930c0 jdk-9+141
+bdafa0cc34a97a2f8db4847a4efd34b407943591 jdk-9+142
+ce81d03ad7320dca3d673374c1a33bc0efd9136a jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java Fri Nov 11 16:44:36 2016 +0100
@@ -746,42 +746,18 @@
// scan XMLDecl
try {
if (fEntityScanner.skipString(xmlDecl)) {
- fMarkupDepth++;
- // NOTE: special case where document starts with a PI
- // whose name starts with "xml" (e.g. "xmlfoo")
- if (XMLChar.isName(fEntityScanner.peekChar())) {
- fStringBuffer.clear();
- fStringBuffer.append("xml");
- while (XMLChar.isName(fEntityScanner.peekChar())) {
- fStringBuffer.append((char)fEntityScanner.scanChar(null));
- }
- String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
- //this function should fill the data.. and set the fEvent object to this event.
- fContentBuffer.clear() ;
- scanPIData(target, fContentBuffer);
- //REVISIT:where else we can set this value to 'true'
- fEntityManager.fCurrentEntity.mayReadChunks = true;
- //return PI event since PI was encountered
- return XMLEvent.PROCESSING_INSTRUCTION ;
+ if (fEntityScanner.peekChar() == ' ') {
+ fMarkupDepth++;
+ scanXMLDeclOrTextDecl(false);
+ } else {
+ // PI, reset position
+ fEntityManager.fCurrentEntity.position = 0;
}
- // standard XML declaration
- else {
- scanXMLDeclOrTextDecl(false);
- //REVISIT:where else we can set this value to 'true'
- fEntityManager.fCurrentEntity.mayReadChunks = true;
- return XMLEvent.START_DOCUMENT;
- }
- } else{
- //REVISIT:where else we can set this value to 'true'
- fEntityManager.fCurrentEntity.mayReadChunks = true;
- //In both case return the START_DOCUMENT. ony difference is that first block will
- //cosume the XML declaration if any.
- return XMLEvent.START_DOCUMENT;
}
-
//START_OF_THE_DOCUMENT
-
+ fEntityManager.fCurrentEntity.mayReadChunks = true;
+ return XMLEvent.START_DOCUMENT;
}
diff -r f71b844f33d1 -r 95af45781076 jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventReader.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventReader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLEventReader.java Fri Nov 11 16:44:36 2016 +0100
@@ -46,7 +46,10 @@
*/
public interface XMLEventReader extends Iterator {
/**
- * Get the next XMLEvent
+ * Gets the next XMLEvent. The initial event is
+ * {@link javax.xml.stream.events.StartDocument StartDocument}.
+ *
+ * @return the next XMLEvent
* @see XMLEvent
* @throws XMLStreamException if there is an error with the underlying XML.
* @throws java.util.NoSuchElementException iteration has no more elements.
@@ -58,12 +61,15 @@
* Returns true if there are more events and false otherwise.
* @return true if the event reader has more events, false otherwise
*/
+ @Override
public boolean hasNext();
/**
* Check the next XMLEvent without reading it from the stream.
* Returns null if the stream is at EOF or has no more XMLEvents.
* A call to peek() will be equal to the next return of next().
+ *
+ * @return the next XMLEvent
* @see XMLEvent
* @throws XMLStreamException
*/
@@ -73,6 +79,8 @@
* Reads the content of a text-only element. Precondition:
* the current event is START_ELEMENT. Postcondition:
* The current event is the corresponding END_ELEMENT.
+ *
+ * @return the text of the element
* @throws XMLStreamException if the current event is not a START_ELEMENT
* or if a non text element is encountered
*/
@@ -85,6 +93,8 @@
* be used when processing element-only content because
* the parser is not able to recognize ignorable whitespace if
* the DTD is missing or not interpreted.
+ *
+ * @return a START_ELEMENT or END_ELEMENT
* @throws XMLStreamException if anything other than space characters are encountered
*/
public XMLEvent nextTag() throws XMLStreamException;
diff -r f71b844f33d1 -r 95af45781076 jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java
--- a/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/src/java.xml/share/classes/javax/xml/stream/XMLStreamReader.java Fri Nov 11 16:44:36 2016 +0100
@@ -28,7 +28,6 @@
package javax.xml.stream;
-import java.io.Reader;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@@ -37,19 +36,26 @@
* It is designed to be the lowest level and most efficient way to
* read XML data.
*
- *
The XMLStreamReader is designed to iterate over XML using
+ *
+ * The XMLStreamReader is designed to iterate over XML using
* next() and hasNext(). The data can be accessed using methods such as getEventType(),
* getNamespaceURI(), getLocalName() and getText();
*
- *
The next() method causes the reader to read the next parse event.
- * The next() method returns an integer which identifies the type of event just read.
- *
The event type can be determined using getEventType().
- *
Parsing events are defined as the XML Declaration, a DTD,
+ *
+ * An XMLStreamReader instance is created with an initial event type START_DOCUMENT.
+ * At any moment in time, it has a current event that the methods of the interface
+ * access and may load the next event through the {@link #next() next()} method.
+ * The current event type can be determined by {@link #getEventType getEventType()}, and
+ * the next returned by the {@link #next() next()} method.
+ *
+ *
+ * Parsing events are defined as the XML Declaration, a DTD,
* start tag, character data, white space, end tag, comment,
* or processing instruction. An attribute or namespace event may be encountered
* at the root level of a document as the result of a query operation.
*
- *
For XML 1.0 compliance an XML processor must pass the
+ *
+ * For XML 1.0 compliance an XML processor must pass the
* identifiers of declared unparsed entities, notation declarations and their
* associated identifiers to the application. This information is
* provided through the property API on this interface.
@@ -63,7 +69,8 @@
* These properties can only be accessed during a DTD event and
* are defined to return null if the information is not available.
*
- *
The following table describes which methods are valid in what state.
+ *
+ * The following table describes which methods are valid in what state.
* If a method is called in an invalid state the method will throw a
* java.lang.IllegalStateException.
*
@@ -502,8 +509,10 @@
// public void recycle() throws XMLStreamException;
/**
- * Returns an integer code that indicates the type
- * of the event the cursor is pointing to.
+ * Returns an integer code that indicates the type of the event the cursor is
+ * pointing to. The initial event type is {@link #START_DOCUMENT}.
+ *
+ * @return the type of the current event
*/
public int getEventType();
@@ -590,6 +599,8 @@
/**
* Returns the offset into the text character array where the first
* character (of this text event) is stored.
+ *
+ * @return the starting position of the text in the character array
* @throws java.lang.IllegalStateException if this state is not
* a valid text state.
*/
@@ -598,6 +609,8 @@
/**
* Returns the length of the sequence of characters for this
* Text event within the text character array.
+ *
+ * @return the length of the text
* @throws java.lang.IllegalStateException if this state is not
* a valid text state.
*/
@@ -610,9 +623,11 @@
public String getEncoding();
/**
- * Return true if the current event has text, false otherwise
+ * Return a boolean indicating whether the current event has text.
* The following events have text:
* CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
+ *
+ * @return true if the event has text, false otherwise
*/
public boolean hasText();
@@ -623,6 +638,7 @@
* location and null for the publicId and systemId.
* The location information is only valid until next() is
* called.
+ * @return the location of the cursor
*/
public Location getLocation();
@@ -647,8 +663,10 @@
public String getLocalName();
/**
- * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
- * returns false otherwise
+ * returns a boolean indicating whether the current event has a name
+ * (is a START_ELEMENT or END_ELEMENT).
+ *
+ * @return true if the event has a name, false otherwise
*/
public boolean hasName();
diff -r f71b844f33d1 -r 95af45781076 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Fri Nov 11 16:44:36 2016 +0100
@@ -24,20 +24,16 @@
package javax.xml.parsers.ptests;
import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR;
-import static jaxp.library.JAXPTestUtilities.USER_DIR;
import static jaxp.library.JAXPTestUtilities.tryRunWithTmpPermission;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FilePermission;
import java.io.IOException;
import java.util.PropertyPermission;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-import jaxp.library.JAXPTestUtilities;
-
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@@ -189,8 +185,7 @@
*/
@Test(expectedExceptions = { SAXException.class, IOException.class }, dataProvider = "parser-provider")
public void testParse09(SAXParser saxparser) throws Exception {
- JAXPTestUtilities.tryRunWithTmpPermission(() -> saxparser.parse(" ", new DefaultHandler()),
- new FilePermission(USER_DIR + " ", "read"));
+ saxparser.parse("no-such-file", new DefaultHandler());
}
/**
diff -r f71b844f33d1 -r 95af45781076 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogInvalidPathTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogInvalidPathTest.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 catalog;
+
+import javax.xml.catalog.CatalogFeatures;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8151154
+ * @run testng/othervm catalog.CatalogInvalidPathTest
+ * @summary Verifies that the CatalogFeatures' builder throws
+ * IllegalArgumentException on invalid file inputs.
+ * This test was splitted from CatalogTest.java due to
+ * JDK-8168968, it has to only run without SecurityManager
+ * because an ACE will be thrown for invalid path.
+ */
+public class CatalogInvalidPathTest {
+ /*
+ DataProvider: for testing the verification of file paths by
+ the CatalogFeatures builder
+ */
+ @DataProvider(name = "invalidPaths")
+ public Object[][] getFiles() {
+ return new Object[][]{
+ {null},
+ {""},
+ {"file:a/b\\c"},
+ {"file:/../../.."},
+ {"c:/te:t"},
+ {"c:/te?t"},
+ {"c/te*t"},
+ {"in|valid.txt"},
+ {"shema:invalid.txt"},
+ };
+ }
+
+ @Test(dataProvider = "invalidPaths", expectedExceptions = IllegalArgumentException.class)
+ public void testFileInput(String file) {
+ CatalogFeatures features = CatalogFeatures.builder()
+ .with(CatalogFeatures.Feature.FILES, file)
+ .build();
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Fri Nov 11 16:44:36 2016 +0100
@@ -23,18 +23,16 @@
package catalog;
import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
-import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Paths;
-import java.util.PropertyPermission;
+
import javax.xml.XMLConstants;
import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException;
@@ -57,7 +55,6 @@
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
-import jaxp.library.JAXPTestUtilities;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
@@ -73,7 +70,7 @@
/*
* @test
- * @bug 8081248 8144966 8146606 8146237 8151154 8150969 8151162 8152527 8154220 8163232
+ * @bug 8081248 8144966 8146606 8146237 8150969 8151162 8152527 8154220 8163232
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogTest
* @run testng/othervm catalog.CatalogTest
@@ -459,21 +456,6 @@
Catalog catalog = CatalogManager.catalog(features, catalogFile);
}
- /**
- * @bug 8151154
- * Verifies that the CatalogFeatures' builder throws IllegalArgumentException
- * on invalid file inputs.
- * @param file the file path
- */
- @Test(dataProvider = "invalidPaths", expectedExceptions = IllegalArgumentException.class)
- public void testFileInput(String file) {
- JAXPTestUtilities.runWithTmpPermission(() -> {
- CatalogFeatures features = CatalogFeatures.builder()
- .with(CatalogFeatures.Feature.FILES, file)
- .build();
- }, new FilePermission("/../../..", "read"), new FilePermission("c:\\te:t", "read"),
- new FilePermission("c:\\te?t", "read"), new PropertyPermission("user.dir", "read"));
- }
/**
* @bug 8146237
@@ -736,24 +718,6 @@
};
}
- /*
- DataProvider: for testing the verification of file paths by
- the CatalogFeatures builder
- */
- @DataProvider(name = "invalidPaths")
- public Object[][] getFiles() {
- return new Object[][]{
- {null},
- {""},
- {"file:a/b\\c"},
- {"file:/../../.."},
- {"c:/te:t"},
- {"c:/te?t"},
- {"c/te*t"},
- {"in|valid.txt"},
- {"shema:invalid.txt"},
- };
- }
/*
DataProvider: provides test name, expected string, the catalog, and XML
diff -r f71b844f33d1 -r 95af45781076 jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamReaderTest/BugTest.java
--- a/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamReaderTest/BugTest.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamReaderTest/BugTest.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,17 +24,20 @@
package stream.XMLStreamReaderTest;
import java.io.StringReader;
+import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import org.testng.Assert;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/*
* @test
+ * @bug 8069098
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true stream.XMLStreamReaderTest.BugTest
* @run testng/othervm stream.XMLStreamReaderTest.BugTest
@@ -43,11 +46,70 @@
@Listeners({jaxp.library.BasePolicy.class})
public class BugTest {
- @Test
- public static void test1() throws Exception {
- XMLInputFactory xif = XMLInputFactory.newInstance(); // new
- // com.sun.xml.stream.ZephyrParserFactory();
- XMLStreamReader r = xif.createXMLStreamReader(new StringReader(""));
- Assert.assertEquals(XMLStreamConstants.START_DOCUMENT, r.getEventType());
+ /**
+ * Verifies that the initial event of an XMLStreamReader instance is
+ * START_DOCUMENT.
+ *
+ * @param xml the xml input
+ * @param type1 the type of the 1st event
+ * @param type2 the type of the 2nd event
+ * @throws Exception if the test fails to run properly
+ */
+ @Test(dataProvider = "xmls")
+ public static void test1(String xml, int type1, int type2) throws Exception {
+ XMLInputFactory factory = XMLInputFactory.newFactory();
+
+ XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(xml));
+ int type1stEvent = reader.getEventType();
+ int type2ndEvent = reader.next();
+ System.out.println("First event: " + type1stEvent);
+ System.out.println("2nd event: " + type2ndEvent);
+ Assert.assertEquals(type1, type1stEvent);
+ Assert.assertEquals(type2, type2ndEvent);
+ }
+
+
+ /**
+ * Verifies that the initial event of an XMLEventReader instance is
+ * START_DOCUMENT. XMLEventReader depends on XMLStreamReader.
+ *
+ * @param xml the xml input
+ * @param type1 the type of the 1st event
+ * @param type2 the type of the 2nd event
+ * @throws Exception if the test fails to run properly
+ */
+ @Test(dataProvider = "xmls")
+ public static void test2(String xml, int type1, int type2) throws Exception {
+ XMLInputFactory factory = XMLInputFactory.newFactory();
+
+ XMLEventReader reader = factory.createXMLEventReader(new StringReader(xml));
+ int type1stEvent = reader.nextEvent().getEventType();
+ int type2ndEvent = reader.nextEvent().getEventType();
+ System.out.println("First event: " + type1stEvent);
+ System.out.println("2nd event: " + type2ndEvent);
+ Assert.assertEquals(type1, type1stEvent);
+ Assert.assertEquals(type2, type2ndEvent);
+ }
+
+ /*
+ DataProvider: for testing beginning event type
+ Data: xml, 1st event type, 2nd event type
+ */
+ @DataProvider(name = "xmls")
+ public Object[][] getXMLs() {
+
+ return new Object[][]{
+ {"",
+ XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.START_ELEMENT},
+ {"",
+ XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.START_ELEMENT},
+ {""
+ + "" +
+ "",
+ XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.PROCESSING_INSTRUCTION},
+ {"" +
+ "",
+ XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.PROCESSING_INSTRUCTION},
+ };
}
}
diff -r f71b844f33d1 -r 95af45781076 jaxws/.hgtags
--- a/jaxws/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/jaxws/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -387,3 +387,5 @@
7a7aadf3c4500cc273c889aa1172d4fe3844bb6b jdk-9+139
9004617323fe99cbe4fad48f373cb2ed4fc50aa6 jdk-9+140
b2c18f755228d1d19a86cd7d5fa1abb6b1495dfb jdk-9+141
+59101416d90160cfcb4f45dfbccaec15e2c27a29 jdk-9+142
+1c988e708a06257119d54d8a57e99e3b0f37ff18 jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 jdk/.hgtags
--- a/jdk/.hgtags Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/.hgtags Fri Nov 11 16:44:36 2016 +0100
@@ -384,3 +384,5 @@
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
e93b7ea559759f036c9f69fd2ddaf47bb4e98385 jdk-9+140
8d752af5f61d41f226adf2cda72a20faa9ad620a jdk-9+141
+6ce43dd8e954b452f330dd7a412df5107f7e1923 jdk-9+142
+8dbc8594f9d5149bf1c22221272284609408227a jdk-9+143
diff -r f71b844f33d1 -r 95af45781076 jdk/make/GenerateClasslist.gmk
--- a/jdk/make/GenerateClasslist.gmk Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-################################################################################
-# Generate classlist
-################################################################################
-
-default: all
-
-include $(SPEC)
-include MakeBase.gmk
-include Tools.gmk
-include JarArchive.gmk
-
-################################################################################
-# Create a jar with our generator class. Using a jar is intentional since it
-# will load more classes
-
-$(eval $(call SetupJarArchive, CLASSLIST_JAR, \
- SRCS := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
- INCLUDES := build/tools/classlist, \
- JAR := $(SUPPORT_OUTPUTDIR)/classlist.jar, \
-))
-
-TARGETS += $(CLASSLIST_JAR)
-
-################################################################################
-
-CLASSLIST_FILE := $(SUPPORT_OUTPUTDIR)/classlist/classlist
-
-JLI_TRACE_FILE := $(SUPPORT_OUTPUTDIR)/classlist/jli_trace.out
-
-# If an external buildjdk has been supplied, we don't build a separate interim
-# image, so just use the external build jdk instead.
-ifeq ($(EXTERNAL_BUILDJDK), true)
- INTERIM_IMAGE_DIR := $(BUILD_JDK)
-endif
-
-$(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
- $(call MakeDir, $(@D))
- $(call LogInfo, Generating lib/classlist)
- $(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@ \
- -Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
- -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
- build.tools.classlist.HelloClasslist \
- $(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
-
-TARGETS += $(CLASSLIST_FILE)
-
-################################################################################
-
-all: $(TARGETS)
diff -r f71b844f33d1 -r 95af45781076 jdk/make/copy/Copy-java.base.gmk
--- a/jdk/make/copy/Copy-java.base.gmk Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/copy/Copy-java.base.gmk Fri Nov 11 16:44:36 2016 +0100
@@ -33,7 +33,6 @@
#
TARGETS += \
$(INCLUDE_DST_DIR)/jni.h \
- $(INCLUDE_DST_DIR)/jvmti.h \
$(INCLUDE_DST_DIR)/jvmticmlr.h \
$(INCLUDE_DST_DIR)/classfile_constants.h \
$(INCLUDE_DST_OS_DIR)/jni_md.h \
diff -r f71b844f33d1 -r 95af45781076 jdk/make/data/tzdata/VERSION
--- a/jdk/make/data/tzdata/VERSION Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/data/tzdata/VERSION Fri Nov 11 16:44:36 2016 +0100
@@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
-tzdata2016g
+tzdata2016h
diff -r f71b844f33d1 -r 95af45781076 jdk/make/data/tzdata/asia
--- a/jdk/make/data/tzdata/asia Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/data/tzdata/asia Fri Nov 11 16:44:36 2016 +0100
@@ -2567,11 +2567,6 @@
# From Paul Eggert (2015-03-03):
# http://www.timeanddate.com/time/change/west-bank/ramallah?year=2014
# says that the fall 2014 transition was Oct 23 at 24:00.
-# For future dates, guess the last Friday in March at 24:00 through
-# the first Friday on or after October 21 at 00:00. This is consistent with
-# the predictions in today's editions of the following URLs:
-# http://www.timeanddate.com/time/change/gaza-strip/gaza
-# http://www.timeanddate.com/time/change/west-bank/hebron
# From Hannah Kreitem (2016-03-09):
# http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728
@@ -2581,7 +2576,21 @@
#
# From Paul Eggert (2016-03-12):
# Predict spring transitions on March's last Saturday at 01:00 from now on.
-# Leave fall predictions alone for now.
+
+# From Sharef Mustafa (2016-10-19):
+# [T]he Palestinian cabinet decision (Mar 8th 2016) published on
+# http://www.palestinecabinet.gov.ps/WebSite/Upload/Decree/GOV_17/16032016134830.pdf
+# states that summer time will end on Oct 29th at 01:00.
+#
+# From Tim Parenti (2016-10-19):
+# Predict fall transitions on October's last Saturday at 01:00 from now on.
+# This is consistent with the 2016 transition as well as our spring
+# predictions.
+#
+# From Paul Eggert (2016-10-19):
+# It's also consistent with predictions in the following URLs today:
+# http://www.timeanddate.com/time/change/gaza-strip/gaza
+# http://www.timeanddate.com/time/change/west-bank/hebron
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2610,9 +2619,10 @@
Rule Palestine 2012 2014 - Mar lastThu 24:00 1:00 S
Rule Palestine 2012 only - Sep 21 1:00 0 -
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
-Rule Palestine 2014 max - Oct Fri>=21 0:00 0 -
+Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S
+Rule Palestine 2016 max - Oct lastSat 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
@@ -2762,45 +2772,31 @@
# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
-# From K Sethu (2006-04-25):
-# I think the abbreviation LKT originated from the world of computers at
-# the time of or subsequent to the time zone changes by SL Government
-# twice in 1996 and probably SL Government or its standardization
-# agencies never declared an abbreviation as a national standard.
-#
-# I recollect before the recent change the government announcements
-# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
-# Time and no mention was made about the abbreviation.
+# From Sadika Sumanapala (2016-10-19):
+# According to http://www.sltime.org (maintained by Measurement Units,
+# Standards & Services Department, Sri Lanka) abbreviation for Sri Lanka
+# standard time is SLST.
#
-# If we look at Sri Lanka Department of Government's "Official News
-# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
-# use SLT as abbreviation in time stamp at the beginning of each news
-# item....
-#
-# Within Sri Lanka I think LKT is well known among computer users and
-# administrators. In my opinion SLT may not be a good choice because the
-# nation's largest telcom / internet operator Sri Lanka Telcom is well
-# known by that abbreviation - simply as SLT (there IP domains are
-# slt.lk and sltnet.lk).
-#
-# But if indeed our government has adopted SLT as standard abbreviation
-# (that we have not known so far) then it is better that it be used for
-# all computers.
-
-# From Paul Eggert (2006-04-25):
-# One possibility is that we wait for a bit for the dust to settle down
-# and then see what people actually say in practice.
+# From Paul Eggert (2016-10-18):
+# "SLST" seems to be reasonably recent and rarely-used outside time
+# zone nerd sources. I searched Google News and found three uses of
+# it in the International Business Times of India in February and
+# March of this year when discussing cricket match times, but nothing
+# since then (though there has been a lot of cricket) and nothing in
+# other English-language news sources. Our old abbreviation "LKT" is
+# even worse. For now, let's use a numeric abbreviation; we can
+# switch to "SLST" if it catches on.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Colombo 5:19:24 - LMT 1880
5:19:32 - MMT 1906 # Moratuwa Mean Time
- 5:30 - IST 1942 Jan 5
- 5:30 0:30 IHST 1942 Sep
- 5:30 1:00 IST 1945 Oct 16 2:00
- 5:30 - IST 1996 May 25 0:00
- 6:30 - LKT 1996 Oct 26 0:30
- 6:00 - LKT 2006 Apr 15 0:30
- 5:30 - IST
+ 5:30 - +0530 1942 Jan 5
+ 5:30 0:30 +0530/+06 1942 Sep
+ 5:30 1:00 +0530/+0630 1945 Oct 16 2:00
+ 5:30 - +0530 1996 May 25 0:00
+ 6:30 - +0630 1996 Oct 26 0:30
+ 6:00 - +06 2006 Apr 15 0:30
+ 5:30 - +0530
# Syria
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
diff -r f71b844f33d1 -r 95af45781076 jdk/make/data/tzdata/australasia
--- a/jdk/make/data/tzdata/australasia Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/data/tzdata/australasia Fri Nov 11 16:44:36 2016 +0100
@@ -373,7 +373,13 @@
# commencing at 2.00 am on Sunday 1st November, 2015 and ending at
# 3.00 am on Sunday 17th January, 2016.
-# From Paul Eggert (2015-09-01):
+# From Raymond Kumar (2016-10-04):
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-6th-NOVEMBER,-2016.aspx
+# "Fiji's daylight savings will begin on Sunday, 6 November 2016, when
+# clocks go forward an hour at 2am to 3am.... Daylight Saving will
+# end at 3.00am on Sunday 15th January 2017."
+
+# From Paul Eggert (2016-10-03):
# For now, guess DST from 02:00 the first Sunday in November to
# 03:00 the third Sunday in January. Although ad hoc, it matches
# transitions since late 2014 and seems more likely to match future
diff -r f71b844f33d1 -r 95af45781076 jdk/make/data/tzdata/europe
--- a/jdk/make/data/tzdata/europe Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/data/tzdata/europe Fri Nov 11 16:44:36 2016 +0100
@@ -1931,7 +1931,7 @@
# Amsterdam mean time.
# The data entries before 1945 are taken from
-# http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm
+# http://www.staff.science.uu.nl/~gent0113/idl/idl.htm
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
@@ -3450,22 +3450,24 @@
# Turkey
-# From Amar Devegowda (2007-01-03):
-# The time zone rules for Istanbul, Turkey have not been changed for years now.
-# ... The latest rules are available at:
-# http://www.timeanddate.com/worldclock/timezone.html?n=107
-# From Steffen Thorsen (2007-01-03):
-# I have been able to find press records back to 1996 which all say that
-# DST started 01:00 local time and end at 02:00 local time. I am not sure
-# what happened before that. One example for each year from 1996 to 2001:
-# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
-# From Paul Eggert (2007-01-03):
-# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
+# From Kıvanç Yazan (2016-09-25):
+# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with
+# no exceptions.
+# 2) 1994's lastSun was overridden with Mar 20 ...
+# Here are official papers:
+# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986
+# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987
+# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988
+# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989
+# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992
+# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995
+# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994
+# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997
+# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000
+# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001
+# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006
+# From Paul Eggert (2016-09-25):
+# Prefer the above sources to Shanks & Pottenger for time stamps after 1985.
# From Steffen Thorsen (2007-03-09):
# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
@@ -3574,10 +3576,10 @@
Rule Turkey 1983 only - Oct 2 0:00 0 -
Rule Turkey 1985 only - Apr 20 0:00 1:00 S
Rule Turkey 1985 only - Sep 28 0:00 0 -
-Rule Turkey 1986 1990 - Mar lastSun 2:00s 1:00 S
-Rule Turkey 1986 1990 - Sep lastSun 2:00s 0 -
-Rule Turkey 1991 2006 - Mar lastSun 1:00s 1:00 S
-Rule Turkey 1991 1995 - Sep lastSun 1:00s 0 -
+Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S
+Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 -
+Rule Turkey 1994 only - Mar 20 1:00s 1:00 S
+Rule Turkey 1995 2006 - Mar lastSun 1:00s 1:00 S
Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Istanbul 1:55:52 - LMT 1880
diff -r f71b844f33d1 -r 95af45781076 jdk/make/data/tzdata/northamerica
--- a/jdk/make/data/tzdata/northamerica Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/data/tzdata/northamerica Fri Nov 11 16:44:36 2016 +0100
@@ -47,8 +47,32 @@
# was the result of his proposals at the Convention of Railroad Trunk Lines
# in New York City (1869-10). His 1870 proposal was based on Washington, DC,
# but in 1872-05 he moved the proposed origin to Greenwich.
-# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
-# and the most of the country soon followed suit.
+
+# From Paul Eggert (2016-09-21):
+# Dowd's proposal left many details unresolved, such as where to draw
+# lines between time zones. The key individual who made time zones
+# work in the US was William Frederick Allen - railway engineer,
+# managing editor of the Travelers' Guide, and secretary of the
+# General Time Convention, a railway standardization group. Allen
+# spent months in dialogs with scientific and railway leaders,
+# developed a workable plan to institute time zones, and presented it
+# to the General Time Convention on 1883-04-11, saying that his plan
+# meant "local time would be practically abolished" - a plus for
+# railway scheduling. By the next convention on 1883-10-11 nearly all
+# railroads had agreed and it took effect on 1883-11-18 at 12:00.
+# That Sunday was called the "day of two noons", as the eastern parts
+# of the new zones observed noon twice. Allen witnessed the
+# transition in New York City, writing:
+#
+# I heard the bells of St. Paul's strike on the old time. Four
+# minutes later, obedient to the electrical signal from the Naval
+# Observatory ... the time-ball made its rapid descent, the chimes
+# of old Trinity rang twelve measured strokes, and local time was
+# abandoned, probably forever.
+#
+# Most of the US soon followed suit. See:
+# Bartky IR. The adoption of standard time. Technol Cult 1989 Jan;30(1):25-56.
+# http://dx.doi.org/10.2307/3105430
# From Paul Eggert (2005-04-16):
# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
diff -r f71b844f33d1 -r 95af45781076 jdk/make/gendata/GendataBreakIterator.gmk
--- a/jdk/make/gendata/GendataBreakIterator.gmk Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/gendata/GendataBreakIterator.gmk Fri Nov 11 16:44:36 2016 +0100
@@ -55,7 +55,6 @@
$(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := $(JDK_TOPDIR)/src/jdk.localedata/share/classes, \
- INCLUDES := $(TEXT_PKG_LD), \
INCLUDE_FILES := \
$(TEXT_PKG_LD)/BreakIteratorRules_th.java \
$(TEXT_PKG_LD)/BreakIteratorInfo_th.java, \
diff -r f71b844f33d1 -r 95af45781076 jdk/make/mapfiles/libjava/mapfile-vers
--- a/jdk/make/mapfiles/libjava/mapfile-vers Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Fri Nov 11 16:44:36 2016 +0100
@@ -140,7 +140,6 @@
Java_java_lang_Double_doubleToRawLongBits;
Java_java_lang_Float_intBitsToFloat;
Java_java_lang_Float_floatToRawIntBits;
- Java_java_lang_StackFrameInfo_toStackTraceElement0;
Java_java_lang_StackStreamFactory_checkStackWalkModes;
Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
@@ -215,6 +214,8 @@
Java_java_lang_SecurityManager_currentLoadedClass0;
Java_java_lang_SecurityManager_getClassContext;
Java_java_lang_Shutdown_halt0;
+ Java_java_lang_StackTraceElement_initStackTraceElement;
+ Java_java_lang_StackTraceElement_initStackTraceElements;
Java_java_lang_String_intern;
Java_java_lang_StringCoding_err;
Java_java_lang_StringUTF16_isBigEndian;
@@ -227,7 +228,6 @@
Java_java_lang_System_setOut0;
Java_java_lang_Thread_registerNatives;
Java_java_lang_Throwable_fillInStackTrace;
- Java_java_lang_Throwable_getStackTraceElements;
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2;
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2Ljava_security_AccessControlContext_2;
Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedExceptionAction_2;
diff -r f71b844f33d1 -r 95af45781076 jdk/make/mapfiles/libjava/reorder-sparc
--- a/jdk/make/mapfiles/libjava/reorder-sparc Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/mapfiles/libjava/reorder-sparc Fri Nov 11 16:44:36 2016 +0100
@@ -78,7 +78,7 @@
text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess;
text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceElements;
+text: .text%Java_java_lang_StackTraceElement_initStackTraceElements;
text: .text%throwFileNotFoundException;
text: .text%JNU_NotifyAll;
# Test LoadFrame
diff -r f71b844f33d1 -r 95af45781076 jdk/make/mapfiles/libjava/reorder-sparcv9
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9 Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/mapfiles/libjava/reorder-sparcv9 Fri Nov 11 16:44:36 2016 +0100
@@ -74,7 +74,7 @@
text: .text%JNU_GetEnv;
text: .text%Java_java_io_UnixFileSystem_checkAccess;
text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceElements;
+text: .text%Java_java_lang_StackTraceElement_initStackTraceElements;
text: .text%throwFileNotFoundException: OUTPUTDIR/io_util.o;
text: .text%JNU_NotifyAll;
# Test LoadFrame
diff -r f71b844f33d1 -r 95af45781076 jdk/make/mapfiles/libjava/reorder-x86
--- a/jdk/make/mapfiles/libjava/reorder-x86 Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/mapfiles/libjava/reorder-x86 Fri Nov 11 16:44:36 2016 +0100
@@ -78,7 +78,7 @@
text: .text%Java_sun_reflect_NativeMethodAccessorImpl_invoke0;
text: .text%Java_java_io_FileInputStream_available;
text: .text%Java_java_lang_reflect_Array_newArray;
-text: .text%Java_java_lang_Throwable_getStackTraceElements;
+text: .text%Java_java_lang_StackTraceElement_initStackTraceElements;
text: .text%Java_java_lang_System_identityHashCode;
text: .text%JNU_NotifyAll;
# Test LoadFrame
diff -r f71b844f33d1 -r 95af45781076 jdk/make/mapfiles/libsplashscreen/mapfile-vers
--- a/jdk/make/mapfiles/libsplashscreen/mapfile-vers Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/mapfiles/libsplashscreen/mapfile-vers Fri Nov 11 16:44:36 2016 +0100
@@ -44,6 +44,7 @@
SplashSetFileJarName;
SplashSetScaleFactor;
SplashGetScaledImageName;
+ SplashGetScaledImgNameMaxPstfixLen;
local:
*;
};
diff -r f71b844f33d1 -r 95af45781076 jdk/make/rmic/Rmic-java.rmi.gmk
--- a/jdk/make/rmic/Rmic-java.rmi.gmk Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/make/rmic/Rmic-java.rmi.gmk Fri Nov 11 16:44:36 2016 +0100
@@ -33,7 +33,7 @@
#
$(eval $(call SetupRMICompilation,RMI_12, \
- CLASSES := sun.rmi.server.Activation$$$$ActivationSystemImpl \
+ CLASSES := sun.rmi.server.Activation$$ActivationSystemImpl \
java.rmi.activation.ActivationGroup, \
CLASSES_DIR := $(CLASSES_DIR)/java.rmi, \
STUB_CLASSES_DIR := $(STUB_CLASSES_DIR)/java.rmi, \
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/io/File.java
--- a/jdk/src/java.base/share/classes/java/io/File.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/File.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1907,16 +1907,10 @@
throws IOException
{
long n = random.nextLong();
- if (n == Long.MIN_VALUE) {
- n = 0; // corner case
- } else {
- n = Math.abs(n);
- }
// Use only the file name from the supplied prefix
prefix = (new File(prefix)).getName();
-
- String name = prefix + Long.toString(n) + suffix;
+ String name = prefix + Long.toUnsignedString(n) + suffix;
File f = new File(dir, name);
if (!name.equals(f.getName()) || f.isInvalid()) {
if (System.getSecurityManager() != null)
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/io/FileInputStream.java
--- a/jdk/src/java.base/share/classes/java/io/FileInputStream.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/FileInputStream.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package java.io;
import java.nio.channels.FileChannel;
-import java.util.concurrent.atomic.AtomicBoolean;
import sun.nio.ch.FileChannelImpl;
@@ -60,7 +59,9 @@
private volatile FileChannel channel;
- private final AtomicBoolean closed = new AtomicBoolean(false);
+ private final Object closeLock = new Object();
+
+ private volatile boolean closed;
/**
* Creates a FileInputStream
by
@@ -313,14 +314,21 @@
* @spec JSR-51
*/
public void close() throws IOException {
- if (!closed.compareAndSet(false, true)) {
- // if compareAndSet() returns false closed was already true
+ if (closed) {
return;
}
+ synchronized (closeLock) {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ }
FileChannel fc = channel;
if (fc != null) {
- fc.close();
+ // possible race with getChannel(), benign since
+ // FileChannel.close is final and idempotent
+ fc.close();
}
fd.closeAll(new Closeable() {
@@ -370,8 +378,10 @@
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, true, false, this);
- if (closed.get()) {
+ if (closed) {
try {
+ // possible race with close(), benign since
+ // FileChannel.close is final and idempotent
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/io/FileOutputStream.java
--- a/jdk/src/java.base/share/classes/java/io/FileOutputStream.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/FileOutputStream.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package java.io;
import java.nio.channels.FileChannel;
-import java.util.concurrent.atomic.AtomicBoolean;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import sun.nio.ch.FileChannelImpl;
@@ -77,7 +76,9 @@
*/
private final String path;
- private final AtomicBoolean closed = new AtomicBoolean(false);
+ private final Object closeLock = new Object();
+
+ private volatile boolean closed;
/**
* Creates a file output stream to write to the file with the
@@ -341,14 +342,21 @@
* @spec JSR-51
*/
public void close() throws IOException {
- if (!closed.compareAndSet(false, true)) {
- // if compareAndSet() returns false closed was already true
+ if (closed) {
return;
}
+ synchronized (closeLock) {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ }
FileChannel fc = channel;
if (fc != null) {
- fc.close();
+ // possible race with getChannel(), benign since
+ // FileChannel.close is final and idempotent
+ fc.close();
}
fd.closeAll(new Closeable() {
@@ -399,8 +407,10 @@
fc = this.channel;
if (fc == null) {
this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
- if (closed.get()) {
+ if (closed) {
try {
+ // possible race with close(), benign since
+ // FileChannel.close is final and idempotent
fc.close();
} catch (IOException ioe) {
throw new InternalError(ioe); // should not happen
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/io/FilePermission.java
--- a/jdk/src/java.base/share/classes/java/io/FilePermission.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/FilePermission.java Fri Nov 11 16:44:36 2016 +0100
@@ -173,6 +173,7 @@
private transient Path npath; // normalized dir path.
private transient Path npath2; // alternative normalized dir path.
private transient boolean allFiles; // whether this is <>
+ private transient boolean invalid; // whether input path is invalid
// static Strings used by init(int mask)
private static final char RECURSIVE_CHAR = '-';
@@ -218,11 +219,12 @@
* A private constructor like a clone, only npath2 is not touched.
* @param input
*/
- private FilePermission(FilePermission input) {
- super(input.getName());
+ private FilePermission(String name, FilePermission input) {
+ super(name);
this.npath = input.npath;
this.actions = input.actions;
this.allFiles = input.allFiles;
+ this.invalid = input.invalid;
this.recursive = input.recursive;
this.directory = input.directory;
this.cpath = input.cpath;
@@ -255,7 +257,12 @@
if (input.npath2 == null && !input.allFiles) {
Path npath2 = altPath(input.npath);
if (npath2 != null) {
- FilePermission np = new FilePermission(input);
+ // Please note the name of the new permission is
+ // different than the original so that when one is
+ // added to a FilePermissionCollection it will not
+ // be merged with the original one.
+ FilePermission np = new FilePermission(
+ input.getName()+"#plus", input);
np.npath2 = npath2;
return np;
}
@@ -266,7 +273,9 @@
if (!input.allFiles) {
Path npath2 = altPath(input.npath);
if (npath2 != null) {
- FilePermission np = new FilePermission(input);
+ // New name, see above.
+ FilePermission np = new FilePermission(
+ input.getName()+"#using", input);
np.npath = npath2;
return np;
}
@@ -318,11 +327,12 @@
// Windows. Some JDK codes generate such illegal names.
npath = builtInFS.getPath(new File(name).getPath())
.normalize();
+ invalid = false;
} catch (InvalidPathException ipe) {
// Still invalid. For compatibility reason, accept it
// but make this permission useless.
npath = builtInFS.getPath("-u-s-e-l-e-s-s-");
- this.mask = NONE;
+ invalid = true;
}
// lastName should always be non-null now
@@ -540,6 +550,12 @@
*/
boolean impliesIgnoreMask(FilePermission that) {
if (FilePermCompat.nb) {
+ if (this == that) {
+ return true;
+ }
+ if (this.invalid || that.invalid) {
+ return false;
+ }
if (allFiles) {
return true;
}
@@ -687,9 +703,13 @@
FilePermission that = (FilePermission) obj;
if (FilePermCompat.nb) {
+ if (this.invalid || that.invalid) {
+ return false;
+ }
return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.npath.equals(that.npath) &&
+ Objects.equals(npath2, that.npath2) &&
(this.directory == that.directory) &&
(this.recursive == that.recursive);
} else {
@@ -708,7 +728,8 @@
@Override
public int hashCode() {
if (FilePermCompat.nb) {
- return Objects.hash(mask, allFiles, directory, recursive, npath);
+ return Objects.hash(
+ mask, allFiles, directory, recursive, npath, npath2, invalid);
} else {
return 0;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/Class.java
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Fri Nov 11 16:44:36 2016 +0100
@@ -485,7 +485,7 @@
* can be replaced by
*
* {@code
- * clazz.getConstructor().newInstance()
+ * clazz.getDeclaredConstructor().newInstance()
* }
*
* The latter sequence of calls is inferred to be able to throw
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/ClassLoader.java
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Fri Nov 11 16:44:36 2016 +0100
@@ -104,9 +104,9 @@
* class or resource itself.
*
* Class loaders that support concurrent loading of classes are known as
- * parallel capable class loaders and are required to register
- * themselves at their class initialization time by invoking the
- * {@link
+ * {@linkplain #isParallelCapable() parallel capable} class loaders and
+ * are required to register themselves at their class initialization time by
+ * invoking the {@link
* #registerAsParallelCapable ClassLoader.registerAsParallelCapable}
* method. Note that the ClassLoader class is registered as parallel
* capable by default. However, its subclasses still need to register themselves
@@ -222,6 +222,9 @@
// must be added *after* it.
private final ClassLoader parent;
+ // class loader name
+ private final String name;
+
// the unnamed module for this ClassLoader
private final Module unnamedModule;
@@ -331,6 +334,14 @@
}
private static Void checkCreateClassLoader() {
+ return checkCreateClassLoader(null);
+ }
+
+ private static Void checkCreateClassLoader(String name) {
+ if (name != null && name.isEmpty()) {
+ throw new IllegalArgumentException("name must be non-empty or null");
+ }
+
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
@@ -338,7 +349,8 @@
return null;
}
- private ClassLoader(Void unused, ClassLoader parent) {
+ private ClassLoader(Void unused, String name, ClassLoader parent) {
+ this.name = name;
this.parent = parent;
this.unnamedModule
= SharedSecrets.getJavaLangReflectModuleAccess()
@@ -356,6 +368,27 @@
}
/**
+ * Creates a new class loader of the specified name and using the
+ * specified parent class loader for delegation.
+ *
+ * @param name class loader name; or {@code null} if not named
+ * @param parent the parent class loader
+ *
+ * @throws IllegalArgumentException if the given name is empty.
+ *
+ * @throws SecurityException
+ * If a security manager exists and its
+ * {@link SecurityManager#checkCreateClassLoader()}
+ * method doesn't allow creation of a new class loader.
+ *
+ * @since 9
+ */
+ protected ClassLoader(String name, ClassLoader parent) {
+ this(checkCreateClassLoader(name), name, parent);
+ }
+
+
+ /**
* Creates a new class loader using the specified parent class loader for
* delegation.
*
@@ -375,9 +408,10 @@
* @since 1.2
*/
protected ClassLoader(ClassLoader parent) {
- this(checkCreateClassLoader(), parent);
+ this(checkCreateClassLoader(), null, parent);
}
+
/**
* Creates a new class loader using the ClassLoader returned by
* the method {@link #getSystemClassLoader()
@@ -394,7 +428,31 @@
* of a new class loader.
*/
protected ClassLoader() {
- this(checkCreateClassLoader(), getSystemClassLoader());
+ this(checkCreateClassLoader(), null, getSystemClassLoader());
+ }
+
+
+ /**
+ * Returns the name of this class loader or {@code null} if
+ * this class loader is not named.
+ *
+ * @apiNote This method is non-final for compatibility. If this
+ * method is overridden, this method must return the same name
+ * as specified when this class loader was instantiated.
+ *
+ * @return name of this class loader; or {@code null} if
+ * this class loader is not named.
+ *
+ * @since 9
+ */
+ public String getName() {
+ return name;
+ }
+
+ // package-private used by StackTraceElement to avoid
+ // calling the overrideable getName method
+ final String name() {
+ return name;
}
// -- Class --
@@ -1437,7 +1495,7 @@
}
/**
- * Registers the caller as parallel capable.
+ * Registers the caller as {@linkplain #isParallelCapable() parallel capable}.
* The registration succeeds if and only if all of the following
* conditions are met:
*
@@ -1448,8 +1506,10 @@
* Note that once a class loader is registered as parallel capable, there
* is no way to change it back.
*
- * @return true if the caller is successfully registered as
- * parallel capable and false if otherwise.
+ * @return {@code true} if the caller is successfully registered as
+ * parallel capable and {@code false} if otherwise.
+ *
+ * @see #isParallelCapable()
*
* @since 1.7
*/
@@ -1461,6 +1521,22 @@
}
/**
+ * Returns {@code true} if this class loader is
+ * {@linkplain #registerAsParallelCapable parallel capable}, otherwise
+ * {@code false}.
+ *
+ * @return {@code true} if this class loader is parallel capable,
+ * otherwise {@code false}.
+ *
+ * @see #registerAsParallelCapable()
+ *
+ * @since 9
+ */
+ public final boolean isParallelCapable() {
+ return ParallelLoaders.isRegistered(this.getClass());
+ }
+
+ /**
* Find a resource of the specified name from the search path used to load
* classes. This method locates the resource through the system class
* loader (see {@link #getSystemClassLoader()}).
@@ -1610,6 +1686,9 @@
* platform classes are visible to
* the platform class loader.
*
+ * @implNote The name of the builtin platform class loader is
+ * {@code "platform"}.
+ *
* @return The platform {@code ClassLoader}.
*
* @throws SecurityException
@@ -1663,6 +1742,16 @@
* this method during startup should take care not to cache the return
* value until the system is fully initialized.
*
+ * The name of the built-in system class loader is {@code "app"}.
+ * The class path used by the built-in system class loader is determined
+ * by the system property "{@code java.class.path}" during early
+ * initialization of the VM. If the system property is not defined,
+ * or its value is an empty string, then there is no class path
+ * when the initial module is a module on the application module path,
+ * i.e. a named module. If the initial module is not on
+ * the application module path then the class path defaults to
+ * the current working directory.
+ *
* @return The system ClassLoader for delegation
*
* @throws SecurityException
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java
--- a/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java Fri Nov 11 16:44:36 2016 +0100
@@ -112,11 +112,6 @@
return toStackTraceElement().toString();
}
- /**
- * Fill in the fields of the given StackTraceElement
- */
- private native void toStackTraceElement0(StackTraceElement ste);
-
@Override
public StackTraceElement toStackTraceElement() {
StackTraceElement s = ste;
@@ -124,9 +119,7 @@
synchronized (this) {
s = ste;
if (s == null) {
- s = new StackTraceElement();
- toStackTraceElement0(s);
- ste = s;
+ ste = s = StackTraceElement.of(this);
}
}
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/StackTraceElement.java
--- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Fri Nov 11 16:44:36 2016 +0100
@@ -25,7 +25,18 @@
package java.lang;
+import jdk.internal.loader.BuiltinClassLoader;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.VM;
+import jdk.internal.module.ModuleHashes;
+
+import java.lang.module.ModuleDescriptor.Version;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.HashSet;
import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
/**
* An element in a stack trace, as returned by {@link
@@ -40,7 +51,15 @@
* @author Josh Bloch
*/
public final class StackTraceElement implements java.io.Serializable {
- // Normally initialized by VM (public constructor added in 1.5)
+ // This field is set to the compacted String representation used
+ // by StackTraceElement::toString and stored in serial form.
+ //
+ // This field is of Object type. VM initially sets this field to
+ // the Class object of the declaring class to build the compacted string.
+ private Object classOrLoaderModuleClassName;
+
+ // Normally initialized by VM
+ private String classLoaderName;
private String moduleName;
private String moduleVersion;
private String declaringClass;
@@ -72,19 +91,22 @@
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
- this(null, null, declaringClass, methodName, fileName, lineNumber);
+ this(null, null, null, declaringClass, methodName, fileName, lineNumber);
}
/**
* Creates a stack trace element representing the specified execution
* point.
*
+ * @param classLoaderName the class loader name if the class loader of
+ * the class containing the execution point represented by
+ * the stack trace is named; otherwise {@code null}
* @param moduleName the module name if the class containing the
* execution point represented by the stack trace is in a named
- * module; can be {@code null}
+ * module; otherwise {@code null}
* @param moduleVersion the module version if the class containing the
* execution point represented by the stack trace is in a named
- * module that has a version; can be {@code null}
+ * module that has a version; otherwise {@code null}
* @param declaringClass the fully qualified name of the class containing
* the execution point represented by the stack trace element
* @param methodName the name of the method containing the execution point
@@ -97,26 +119,30 @@
* a negative number if this information is unavailable. A value
* of -2 indicates that the method containing the execution point
* is a native method
+ *
* @throws NullPointerException if {@code declaringClass} is {@code null}
* or {@code methodName} is {@code null}
+ *
* @since 9
*/
- public StackTraceElement(String moduleName, String moduleVersion,
+ public StackTraceElement(String classLoaderName,
+ String moduleName, String moduleVersion,
String declaringClass, String methodName,
String fileName, int lineNumber) {
- this.moduleName = moduleName;
- this.moduleVersion = moduleVersion;
- this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
- this.methodName = Objects.requireNonNull(methodName, "Method name is null");
- this.fileName = fileName;
- this.lineNumber = lineNumber;
+ this.classLoaderName = classLoaderName;
+ this.moduleName = moduleName;
+ this.moduleVersion = moduleVersion;
+ this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
+ this.methodName = Objects.requireNonNull(methodName, "Method name is null");
+ this.fileName = fileName;
+ this.lineNumber = lineNumber;
}
-
- /**
- * Creates an empty stack frame element to be filled in by Throwable.
+ /*
+ * Private constructor for the factory methods to create StackTraceElement
+ * for Throwable and StackFrameInfo
*/
- StackTraceElement() { }
+ private StackTraceElement() {}
/**
* Returns the name of the source file containing the execution point
@@ -178,6 +204,21 @@
}
/**
+ * Returns the name of the class loader of the class containing the
+ * execution point represented by this stack trace element.
+ *
+ * @return the name of the class loader of the class containing the execution
+ * point represented by this stack trace element; {@code null}
+ * if the class loader is not named.
+ *
+ * @since 9
+ * @see java.lang.ClassLoader#getName()
+ */
+ public String getClassLoaderName() {
+ return classLoaderName;
+ }
+
+ /**
* Returns the fully qualified name of the class containing the
* execution point represented by this stack trace element.
*
@@ -220,38 +261,83 @@
* examples may be regarded as typical:
*
* -
- * {@code "MyClass.mash(my.module@9.0/MyClass.java:101)"} - Here,
- * {@code "MyClass"} is the fully-qualified name of the class
- * containing the execution point represented by this stack trace element,
- * {@code "mash"} is the name of the method containing the execution
- * point, {@code "my.module"} is the module name, {@code "9.0"} is the
- * module version, and {@code "101"} is the line number of the source
- * line containing the execution point.
+ * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)}"
+ * - See the description below.
+ *
+ * -
+ * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java)}"
+ * - The line number is unavailable.
+ *
+ * -
+ * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Unknown Source)}"
+ * - Neither the file name nor the line number is available.
+ *
+ * -
+ * "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Native Method)}"
+ * - The method containing the execution point is a native method.
+ *
+ * -
+ * "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}"
+ * - The class of the execution point is defined in the unnamed module of
+ * the class loader named {@code com.foo.loader}.
+ *
+ * -
+ * "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}"
+ * - The class of the execution point is defined in {@code acme} module
+ * loaded by by a built-in class loader such as the application class loader.
+ *
* -
- * {@code "MyClass.mash(my.module@9.0/MyClass.java)"} - As above, but the
- * line number is unavailable.
- *
-
- * {@code "MyClass.mash(my.module@9.0/Unknown Source)"} - As above, but
- * neither the file name nor the line number are available.
- *
-
- * {@code "MyClass.mash(my.module@9.0/Native Method)"} - As above, but
- * neither the file name nor the line number are available, and the
- * method containing the execution point is known to be a native method.
+ * "{@code MyClass.mash(MyClass.java:9)}"
+ * - {@code MyClass} class is on the application class path.
+ *
*
- * If the execution point is not in a named module, {@code "my.module@9.0/"}
- * will be omitted from the above.
+ *
+ * The first example shows a stack trace element consisting of
+ * three elements, each separated by {@code "/"} followed with
+ * the source file name and the line number of the source line
+ * containing the execution point.
+ *
+ * The first element "{@code com.foo.loader}" is
+ * the name of the class loader. The second element "{@code foo@9.0}"
+ * is the module name and version. The third element is the method
+ * containing the execution point; "{@code com.foo.Main"}" is the
+ * fully-qualified class name and "{@code run}" is the name of the method.
+ * "{@code Main.java}" is the source file name and "{@code 101}" is
+ * the line number.
+ *
+ *
If a class is defined in an unnamed module
+ * then the second element is omitted as shown in
+ * "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}".
+ *
+ * If the class loader is a
+ * built-in class loader or is not named then the first element
+ * and its following {@code "/"} are omitted as shown in
+ * "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}".
+ * If the first element is omitted and the module is an unnamed module,
+ * the second element and its following {@code "/"} are also omitted
+ * as shown in "{@code MyClass.mash(MyClass.java:9)}".
*
* @see Throwable#printStackTrace()
*/
public String toString() {
- String mid = "";
- if (moduleName != null) {
- mid = moduleName;
- if (moduleVersion != null)
- mid += "@" + moduleVersion;
- mid += "/";
+ String s = buildLoaderModuleClassName();
+ if (s == null) {
+ // all elements will be included
+ s = "";
+ if (classLoaderName != null && !classLoaderName.isEmpty()) {
+ s += classLoaderName + "/";
+ }
+ if (moduleName != null && !moduleName.isEmpty()) {
+ s += moduleName;
+
+ if (moduleVersion != null && !moduleVersion.isEmpty()) {
+ s += "@" + moduleVersion;
+ }
+ }
+ s = s.isEmpty() ? declaringClass : s + "/" + declaringClass;
}
- return getClassName() + "." + methodName + "(" + mid +
+
+ return s + "." + methodName + "(" +
(isNativeMethod() ? "Native Method)" :
(fileName != null && lineNumber >= 0 ?
fileName + ":" + lineNumber + ")" :
@@ -264,12 +350,14 @@
* point as this instance. Two stack trace elements {@code a} and
* {@code b} are equal if and only if:
*
{@code
- * equals(a.getFileName(), b.getFileName()) &&
- * a.getLineNumber() == b.getLineNumber()) &&
+ * equals(a.getClassLoaderName(), b.getClassLoaderName()) &&
* equals(a.getModuleName(), b.getModuleName()) &&
* equals(a.getModuleVersion(), b.getModuleVersion()) &&
* equals(a.getClassName(), b.getClassName()) &&
* equals(a.getMethodName(), b.getMethodName())
+ * equals(a.getFileName(), b.getFileName()) &&
+ * a.getLineNumber() == b.getLineNumber()
+ *
* }
* where {@code equals} has the semantics of {@link
* java.util.Objects#equals(Object, Object) Objects.equals}.
@@ -285,9 +373,10 @@
if (!(obj instanceof StackTraceElement))
return false;
StackTraceElement e = (StackTraceElement)obj;
- return e.declaringClass.equals(declaringClass) &&
+ return Objects.equals(classLoaderName, e.classLoaderName) &&
Objects.equals(moduleName, e.moduleName) &&
Objects.equals(moduleVersion, e.moduleVersion) &&
+ e.declaringClass.equals(declaringClass) &&
e.lineNumber == lineNumber &&
Objects.equals(methodName, e.methodName) &&
Objects.equals(fileName, e.fileName);
@@ -298,6 +387,7 @@
*/
public int hashCode() {
int result = 31*declaringClass.hashCode() + methodName.hashCode();
+ result = 31*result + Objects.hashCode(classLoaderName);
result = 31*result + Objects.hashCode(moduleName);
result = 31*result + Objects.hashCode(moduleVersion);
result = 31*result + Objects.hashCode(fileName);
@@ -305,5 +395,157 @@
return result;
}
+
+ /**
+ * Build the compacted String representation to be returned by
+ * toString method from the declaring Class object.
+ */
+ synchronized String buildLoaderModuleClassName() {
+ if (classOrLoaderModuleClassName == null)
+ return null;
+
+ if (classOrLoaderModuleClassName instanceof Class) {
+ Class> cls = (Class>)classOrLoaderModuleClassName;
+ classOrLoaderModuleClassName = toLoaderModuleClassName(cls);
+ }
+ return (String)classOrLoaderModuleClassName;
+ }
+
+ /**
+ * Returns // string
+ * representation of the given class.
+ *
+ * If the module is a non-upgradeable JDK module then omit
+ * its version string.
+ *
+ * If the loader has no name, or if the loader is one of the built-in
+ * loaders (`boot`, `platform`, or `app`) then drop the first element
+ * (`/`).
+ *
+ * If the first element has been dropped and the module is unnamed
+ * then drop the second element (`/`).
+ *
+ * If the first element is not dropped and the module is unnamed
+ * then drop ``.
+ */
+ private static String toLoaderModuleClassName(Class> cls) {
+ ClassLoader loader = cls.getClassLoader0();
+ Module m = cls.getModule();
+
+ // First element - class loader name
+ // Call package-private ClassLoader::name method
+ String s = "";
+ if (loader != null && loader.name() != null &&
+ !(loader instanceof BuiltinClassLoader)) {
+ s = loader.name() + "/";
+ }
+
+ // Second element - module name and version
+ if (m != null && m.isNamed()) {
+ s += m.getName();
+ // Include version if it is a user module or upgradeable module
+ //
+ // If it is JDK non-upgradeable module which is recorded
+ // in the hashes in java.base, omit the version.
+ if (!isHashedInJavaBase(m)) {
+ Optional ov = m.getDescriptor().version();
+ if (ov.isPresent()) {
+ String version = "@" + ov.get().toString();
+ s += version;
+ }
+ }
+ }
+
+ // fully-qualified class name
+ return s.isEmpty() ? cls.getName() : s + "/" + cls.getName();
+ }
+
+ /**
+ * Returns true if the module is hashed with java.base.
+ *
+ * This method returns false when running on the exploded image
+ * since JDK modules are not hashed. They have no Version attribute
+ * and so "@" part will be omitted anyway.
+ */
+ private static boolean isHashedInJavaBase(Module m) {
+ // return true if module system is not initialized as the code
+ // must be in java.base
+ if (!VM.isModuleSystemInited())
+ return true;
+
+ return Layer.boot() == m.getLayer() && HashedModules.contains(m);
+ }
+
+ /*
+ * Finds JDK non-upgradeable modules, i.e. the modules that are
+ * included in the hashes in java.base.
+ */
+ private static class HashedModules {
+ static Set HASHED_MODULES = hashedModules();
+
+ static Set hashedModules() {
+ Module javaBase = Layer.boot().findModule("java.base").get();
+ Optional ohashes =
+ SharedSecrets.getJavaLangModuleAccess()
+ .hashes(javaBase.getDescriptor());
+
+ if (ohashes.isPresent()) {
+ Set names = new HashSet<>(ohashes.get().names());
+ names.add("java.base");
+ return names;
+ }
+
+ return Set.of();
+ }
+
+ static boolean contains(Module m) {
+ return HASHED_MODULES.contains(m.getName());
+ }
+ }
+
+
+ /*
+ * Returns an array of StackTraceElements of the given depth
+ * filled from the backtrace of a given Throwable.
+ */
+ static StackTraceElement[] of(Throwable x, int depth) {
+ StackTraceElement[] stackTrace = new StackTraceElement[depth];
+ for (int i = 0; i < depth; i++) {
+ stackTrace[i] = new StackTraceElement();
+ }
+
+ // VM to fill in StackTraceElement
+ initStackTraceElements(stackTrace, x);
+
+ // ensure the proper StackTraceElement initialization
+ for (StackTraceElement ste : stackTrace) {
+ ste.buildLoaderModuleClassName();
+ }
+ return stackTrace;
+ }
+
+ /*
+ * Returns a StackTraceElement from a given StackFrameInfo.
+ */
+ static StackTraceElement of(StackFrameInfo sfi) {
+ StackTraceElement ste = new StackTraceElement();
+ initStackTraceElement(ste, sfi);
+
+ ste.buildLoaderModuleClassName();
+ return ste;
+ }
+
+ /*
+ * Sets the given stack trace elements with the backtrace
+ * of the given Throwable.
+ */
+ private static native void initStackTraceElements(StackTraceElement[] elements,
+ Throwable x);
+ /*
+ * Sets the given stack trace element with the given StackFrameInfo
+ */
+ private static native void initStackTraceElement(StackTraceElement element,
+ StackFrameInfo sfi);
+
private static final long serialVersionUID = 6992337162326171013L;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/Throwable.java
--- a/jdk/src/java.base/share/classes/java/lang/Throwable.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/Throwable.java Fri Nov 11 16:44:36 2016 +0100
@@ -24,7 +24,6 @@
*/
package java.lang;
-import jdk.internal.misc.VM;
import java.io.*;
import java.util.*;
@@ -826,11 +825,7 @@
// backtrace if this is the first call to this method
if (stackTrace == UNASSIGNED_STACK ||
(stackTrace == null && backtrace != null) /* Out of protocol state */) {
- stackTrace = new StackTraceElement[depth];
- for (int i = 0; i < depth; i++) {
- stackTrace[i] = new StackTraceElement();
- }
- getStackTraceElements(stackTrace);
+ stackTrace = StackTraceElement.of(this, depth);
} else if (stackTrace == null) {
return UNASSIGNED_STACK;
}
@@ -882,13 +877,6 @@
}
/**
- * Gets the stack trace elements.
- * @param elements
- * @throws IndexOutOfBoundsException if {@code elements.length != depth }
- */
- private native void getStackTraceElements(StackTraceElement[] elements);
-
- /**
* Reads a {@code Throwable} from a stream, enforcing
* well-formedness constraints on fields. Null entries and
* self-pointers are not allowed in the list of {@code
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Nov 11 16:44:36 2016 +0100
@@ -5347,7 +5347,7 @@
* {@code (V T A...)} must have at least one {@code A} type, and the default iterator
* handle parameter is adjusted to accept the leading {@code A} type, as if by
* the {@link MethodHandle#asType asType} conversion method.
- * The leading {@code A} type must be {@code Iterable} or a subtype thereof, or an array type.
+ * The leading {@code A} type must be {@code Iterable} or a subtype thereof.
* This conversion step, done at loop construction time, must not throw a {@code WrongMethodTypeException}.
*
*
@@ -5374,7 +5374,8 @@
* V iteratedLoop(A... a...) {
* Iterator it = iterator(a...);
* V v = init(a...);
- * for (T t : it) {
+ * while (it.hasNext()) {
+ * T t = it.next();
* v = body(v, t, a...);
* }
* return v;
@@ -5483,49 +5484,59 @@
Objects.requireNonNull(body);
MethodType bodyType = body.type();
Class> returnType = bodyType.returnType();
- List> innerList = bodyType.parameterList();
+ List> internalParamList = bodyType.parameterList();
// strip leading V value if present
int vsize = (returnType == void.class ? 0 : 1);
- if (vsize != 0 && (innerList.size() == 0 || innerList.get(0) != returnType)) {
+ if (vsize != 0 && (internalParamList.size() == 0 || internalParamList.get(0) != returnType)) {
// argument list has no "V" => error
MethodType expected = bodyType.insertParameterTypes(0, returnType);
throw misMatchedTypes("body function", bodyType, expected);
- } else if (innerList.size() <= vsize) {
+ } else if (internalParamList.size() <= vsize) {
// missing T type => error
MethodType expected = bodyType.insertParameterTypes(vsize, Object.class);
throw misMatchedTypes("body function", bodyType, expected);
}
- //Class> elementType = innerList.get(vsize); // do not need this
- List> outerList = innerList.subList(vsize + 1, innerList.size());
- if (outerList.isEmpty()) {
- // special case; take lists from iterator handle
- outerList = ((iterator != null)
- ? iterator.type().parameterList()
- : Arrays.asList(Iterable.class));
- innerList = bodyType.insertParameterTypes(vsize + 1, outerList).parameterList();
- }
+ List> externalParamList = internalParamList.subList(vsize + 1, internalParamList.size());
+ Class> iterableType = null;
if (iterator != null) {
+ // special case; if the body handle only declares V and T then
+ // the external parameter list is obtained from iterator handle
+ if (externalParamList.isEmpty()) {
+ externalParamList = iterator.type().parameterList();
+ }
MethodType itype = iterator.type();
if (!Iterator.class.isAssignableFrom(itype.returnType())) {
throw newIllegalArgumentException("iteratedLoop first argument must have Iterator return type");
}
- if (!itype.effectivelyIdenticalParameters(0, outerList)) {
- MethodType expected = methodType(itype.returnType(), outerList);
+ if (!itype.effectivelyIdenticalParameters(0, externalParamList)) {
+ MethodType expected = methodType(itype.returnType(), externalParamList);
throw misMatchedTypes("iterator parameters", itype, expected);
}
+ } else {
+ if (externalParamList.isEmpty()) {
+ // special case; if the iterator handle is null and the body handle
+ // only declares V and T then the external parameter list consists
+ // of Iterable
+ externalParamList = Arrays.asList(Iterable.class);
+ iterableType = Iterable.class;
+ } else {
+ // special case; if the iterator handle is null and the external
+ // parameter list is not empty then the first parameter must be
+ // assignable to Iterable
+ iterableType = externalParamList.get(0);
+ if (!Iterable.class.isAssignableFrom(iterableType)) {
+ throw newIllegalArgumentException(
+ "inferred first loop argument must inherit from Iterable: " + iterableType);
+ }
+ }
}
if (init != null) {
MethodType initType = init.type();
if (initType.returnType() != returnType ||
- !initType.effectivelyIdenticalParameters(0, outerList)) {
- throw misMatchedTypes("loop initializer", initType, methodType(returnType, outerList));
+ !initType.effectivelyIdenticalParameters(0, externalParamList)) {
+ throw misMatchedTypes("loop initializer", initType, methodType(returnType, externalParamList));
}
}
- Class> iterableType = outerList.isEmpty() ? null : outerList.get(0);
- if (iterableType != null && !Iterable.class.isAssignableFrom(iterableType) && !iterableType.isArray()) {
- throw newIllegalArgumentException(
- "inferred first loop argument must be an array or inherit from Iterable: " + iterableType);
- }
return iterableType; // help the caller a bit
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Fri Nov 11 16:44:36 2016 +0100
@@ -31,6 +31,7 @@
import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.ByteBuffer;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -1997,6 +1998,13 @@
public Optional hashes(ModuleDescriptor descriptor) {
return descriptor.hashes();
}
+
+ @Override
+ public ModuleFinder newModulePath(Runtime.Version version,
+ boolean isLinkPhase,
+ Path... entries) {
+ return new ModulePath(version, isLinkPhase, entries);
+ }
});
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Fri Nov 11 16:44:36 2016 +0100
@@ -228,7 +228,7 @@
*
* If the name matches the regular expression {@code
* "-(\\d+(\\.|$))"} then the module name will be derived from the
- * subsequence proceeding the hyphen of the first occurrence. The
+ * subsequence preceding the hyphen of the first occurrence. The
* subsequence after the hyphen is parsed as a {@link
* ModuleDescriptor.Version} and ignored if it cannot be parsed as
* a {@code Version}.
@@ -248,18 +248,23 @@
* It {@link ModuleDescriptor#requires() requires} {@code
* java.base}.
*
- * All entries in the JAR file with names ending with {@code
- * .class} are assumed to be class files where the name corresponds
- * to the fully qualified name of the class. The packages of all
- * classes are {@link ModuleDescriptor#exports() exported}.
+ * The set of packages in the module is derived from the names
+ * of non-directory entries in the JAR file. A candidate package name
+ * is derived from an entry using the characters up to, but not
+ * including, the last forward slash. All remaining forward slashes are
+ * replaced with dot ({@code "."}). If the resulting string is a valid
+ * Java identifier then it is assumed to be a package name. For example,
+ * if the JAR file contains an entry "{@code p/q/Foo.class}" then the
+ * package name derived is "{@code p.q}". All packages are {@link
+ * ModuleDescriptor#exports() exported}.
*
- * The contents of all entries starting with {@code
+ *
The contents of entries starting with {@code
* META-INF/services/} are assumed to be service configuration files
- * (see {@link java.util.ServiceLoader}). The name of the file
- * (that follows {@code META-INF/services/}) is assumed to be the
- * fully-qualified binary name of a service type. The entries in the
- * file are assumed to be the fully-qualified binary names of
- * provider classes.
+ * (see {@link java.util.ServiceLoader}). If the name of a file
+ * (that follows {@code META-INF/services/}) is a legal Java identifier
+ * then it is assumed to be the fully-qualified binary name of a
+ * service type. The entries in the file are assumed to be the
+ * fully-qualified binary names of provider classes.
*
* If the JAR file has a {@code Main-Class} attribute in its
* main manifest then its value is the {@link
@@ -271,8 +276,8 @@
* {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
* automatic module then {@code FindException} is thrown. This can arise,
* for example, when a legal Java identifier name cannot be derived from
- * the file name of the JAR file or where a package name derived from an
- * entry ending with {@code .class} is not a legal Java identifier.
+ * the file name of the JAR file or where the JAR file contains a {@code
+ * .class} in the top-level directory of the JAR file.
*
* In addition to JAR files, an implementation may also support modules
* that are packaged in other implementation specific module formats. When
@@ -283,8 +288,10 @@
*
*
As with automatic modules, the contents of a packaged or exploded
* module may need to be scanned in order to determine the packages
- * in the module. If a {@code .class} file that corresponds to a class in an
- * unnamed package is encountered then {@code FindException} is thrown.
+ * in the module. If a {@code .class} file (other than {@code
+ * module-info.class}) is found in the top-level directory then it is
+ * assumed to be a class in the unnamed package and so {@code FindException}
+ * is thrown.
*
* Finders created by this method are lazy and do not eagerly check
* that the given file paths are directories or packaged modules.
@@ -341,7 +348,7 @@
* @return A {@code ModuleFinder} that composes a sequence of module finders
*/
static ModuleFinder compose(ModuleFinder... finders) {
- // copy the list, also checking for nulls
+ // copy the list and check for nulls
final List finderList = List.of(finders);
return new ModuleFinder() {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/ModulePath.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModulePath.java Fri Nov 11 16:44:36 2016 +0100
@@ -33,10 +33,12 @@
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor.Requires;
+import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.HashMap;
@@ -52,49 +54,53 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import jdk.internal.jmod.JmodFile;
import jdk.internal.jmod.JmodFile.Section;
-import jdk.internal.module.ConfigurableModuleFinder;
+import jdk.internal.module.Checks;
import jdk.internal.perf.PerfCounter;
+import jdk.internal.util.jar.VersionedStream;
/**
* A {@code ModuleFinder} that locates modules on the file system by searching
* a sequence of directories or packaged modules.
*
- * The {@code ModuleFinder} can be configured to work in either the run-time
+ * The {@code ModuleFinder} can be created to work in either the run-time
* or link-time phases. In both cases it locates modular JAR and exploded
- * modules. When configured for link-time then it additionally locates
+ * modules. When created for link-time then it additionally locates
* modules in JMOD files.
*/
-class ModulePath implements ConfigurableModuleFinder {
+class ModulePath implements ModuleFinder {
private static final String MODULE_INFO = "module-info.class";
+ // the version to use for multi-release modular JARs
+ private final Runtime.Version releaseVersion;
+
+ // true for the link phase (supports modules packaged in JMOD format)
+ private final boolean isLinkPhase;
+
// the entries on this module path
private final Path[] entries;
private int next;
- // true if in the link phase
- private boolean isLinkPhase;
-
// map of module name to module reference map for modules already located
private final Map cachedModules = new HashMap<>();
- ModulePath(Path... entries) {
+ ModulePath(Runtime.Version version, boolean isLinkPhase, Path... entries) {
+ this.releaseVersion = version;
+ this.isLinkPhase = isLinkPhase;
this.entries = entries.clone();
for (Path entry : this.entries) {
Objects.requireNonNull(entry);
}
}
- @Override
- public void configurePhase(Phase phase) {
- isLinkPhase = (phase == Phase.LINK_TIME);
+ ModulePath(Path... entries) {
+ this(JarFile.runtimeVersion(), false, entries);
}
@Override
@@ -239,9 +245,13 @@
if (mref != null) {
// can have at most one version of a module in the directory
String name = mref.descriptor().name();
- if (nameToReference.put(name, mref) != null) {
+ ModuleReference previous = nameToReference.put(name, mref);
+ if (previous != null) {
+ String fn1 = fileName(mref);
+ String fn2 = fileName(previous);
throw new FindException("Two versions of module "
- + name + " found in " + dir);
+ + name + " found in " + dir
+ + " (" + fn1 + " and " + fn2 + ")");
}
}
}
@@ -294,6 +304,25 @@
}
+ /**
+ * Returns a string with the file name of the module if possible.
+ * If the module location is not a file URI then return the URI
+ * as a string.
+ */
+ private String fileName(ModuleReference mref) {
+ URI uri = mref.location().orElse(null);
+ if (uri != null) {
+ if (uri.getScheme().equalsIgnoreCase("file")) {
+ Path file = Paths.get(uri);
+ return file.getFileName().toString();
+ } else {
+ return uri.toString();
+ }
+ } else {
+ return "";
+ }
+ }
+
// -- jmod files --
private Set jmodPackages(JmodFile jf) {
@@ -301,7 +330,7 @@
.filter(e -> e.section() == Section.CLASSES)
.map(JmodFile.Entry::name)
.map(this::toPackageName)
- .filter(pkg -> pkg.length() > 0) // module-info
+ .flatMap(Optional::stream)
.collect(Collectors.toSet());
}
@@ -328,8 +357,8 @@
private static final String SERVICES_PREFIX = "META-INF/services/";
/**
- * Returns a container with the service type corresponding to the name of
- * a services configuration file.
+ * Returns the service type corresponding to the name of a services
+ * configuration file if it is a valid Java identifier.
*
* For example, if called with "META-INF/services/p.S" then this method
* returns a container with the value "p.S".
@@ -341,7 +370,8 @@
String prefix = cf.substring(0, index);
if (prefix.equals(SERVICES_PREFIX)) {
String sn = cf.substring(index);
- return Optional.of(sn);
+ if (Checks.isJavaIdentifier(sn))
+ return Optional.of(sn);
}
}
return Optional.empty();
@@ -416,28 +446,28 @@
if (vs != null)
builder.version(vs);
- // scan the entries in the JAR file to locate the .class and service
- // configuration file
- Map> map =
- versionedStream(jf)
- .map(JarEntry::getName)
- .filter(s -> (s.endsWith(".class") ^ s.startsWith(SERVICES_PREFIX)))
- .collect(Collectors.partitioningBy(s -> s.endsWith(".class"),
- Collectors.toSet()));
- Set classFiles = map.get(Boolean.TRUE);
- Set configFiles = map.get(Boolean.FALSE);
+ // scan the names of the entries in the JAR file
+ Map> map = VersionedStream.stream(jf)
+ .filter(e -> !e.isDirectory())
+ .map(JarEntry::getName)
+ .collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
+ Collectors.toSet()));
+
+ Set resources = map.get(Boolean.FALSE);
+ Set configFiles = map.get(Boolean.TRUE);
// all packages are exported
- classFiles.stream()
- .map(c -> toPackageName(c))
- .distinct()
- .forEach(builder::exports);
+ resources.stream()
+ .map(this::toPackageName)
+ .flatMap(Optional::stream)
+ .distinct()
+ .forEach(builder::exports);
// map names of service configuration files to service names
Set serviceNames = configFiles.stream()
- .map(this::toServiceName)
- .flatMap(Optional::stream)
- .collect(Collectors.toSet());
+ .map(this::toServiceName)
+ .flatMap(Optional::stream)
+ .collect(Collectors.toSet());
// parse each service configuration file
for (String sn : serviceNames) {
@@ -502,25 +532,13 @@
return mn;
}
- private Stream versionedStream(JarFile jf) {
- if (jf.isMultiRelease()) {
- // a stream of JarEntries whose names are base names and whose
- // contents are from the corresponding versioned entries in
- // a multi-release jar file
- return jf.stream().map(JarEntry::getName)
- .filter(name -> !name.startsWith("META-INF/versions/"))
- .map(jf::getJarEntry);
- } else {
- return jf.stream();
- }
- }
-
private Set jarPackages(JarFile jf) {
- return versionedStream(jf)
- .filter(e -> e.getName().endsWith(".class"))
- .map(e -> toPackageName(e.getName()))
- .filter(pkg -> pkg.length() > 0) // module-info
- .collect(Collectors.toSet());
+ return VersionedStream.stream(jf)
+ .filter(e -> !e.isDirectory())
+ .map(JarEntry::getName)
+ .map(this::toPackageName)
+ .flatMap(Optional::stream)
+ .collect(Collectors.toSet());
}
/**
@@ -535,7 +553,7 @@
try (JarFile jf = new JarFile(file.toFile(),
true, // verify
ZipFile.OPEN_READ,
- JarFile.runtimeVersion()))
+ releaseVersion))
{
ModuleDescriptor md;
JarEntry entry = jf.getJarEntry(MODULE_INFO);
@@ -565,11 +583,11 @@
private Set explodedPackages(Path dir) {
try {
return Files.find(dir, Integer.MAX_VALUE,
- ((path, attrs) -> attrs.isRegularFile() &&
- path.toString().endsWith(".class")))
- .map(path -> toPackageName(dir.relativize(path)))
- .filter(pkg -> pkg.length() > 0) // module-info
- .collect(Collectors.toSet());
+ ((path, attrs) -> attrs.isRegularFile()))
+ .map(path -> dir.relativize(path))
+ .map(this::toPackageName)
+ .flatMap(Optional::stream)
+ .collect(Collectors.toSet());
} catch (IOException x) {
throw new UncheckedIOException(x);
}
@@ -595,29 +613,62 @@
return ModuleReferences.newExplodedModule(md, dir);
}
-
- //
+ /**
+ * Maps the name of an entry in a JAR or ZIP file to a package name.
+ *
+ * @throws IllegalArgumentException if the name is a class file in
+ * the top-level directory of the JAR/ZIP file (and it's
+ * not module-info.class)
+ */
+ private Optional toPackageName(String name) {
+ assert !name.endsWith("/");
- // p/q/T.class => p.q
- private String toPackageName(String cn) {
- assert cn.endsWith(".class");
- int start = 0;
- int index = cn.lastIndexOf("/");
- if (index > start) {
- return cn.substring(start, index).replace('/', '.');
+ int index = name.lastIndexOf("/");
+ if (index == -1) {
+ if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
+ throw new IllegalArgumentException(name
+ + " found in top-level directory:"
+ + " (unnamed package not allowed in module)");
+ }
+ return Optional.empty();
+ }
+
+ String pn = name.substring(0, index).replace('/', '.');
+ if (Checks.isJavaIdentifier(pn)) {
+ return Optional.of(pn);
} else {
- return "";
+ // not a valid package name
+ return Optional.empty();
}
}
- private String toPackageName(Path path) {
- String name = path.toString();
- assert name.endsWith(".class");
- int index = name.lastIndexOf(File.separatorChar);
- if (index != -1) {
- return name.substring(0, index).replace(File.separatorChar, '.');
+ /**
+ * Maps the relative path of an entry in an exploded module to a package
+ * name.
+ *
+ * @throws IllegalArgumentException if the name is a class file in
+ * the top-level directory (and it's not module-info.class)
+ */
+ private Optional toPackageName(Path file) {
+ assert file.getRoot() == null;
+
+ Path parent = file.getParent();
+ if (parent == null) {
+ String name = file.toString();
+ if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
+ throw new IllegalArgumentException(name
+ + " found in in top-level directory"
+ + " (unnamed package not allowed in module)");
+ }
+ return Optional.empty();
+ }
+
+ String pn = parent.toString().replace(File.separatorChar, '.');
+ if (Checks.isJavaIdentifier(pn)) {
+ return Optional.of(pn);
} else {
- return "";
+ // not a valid package name
+ return Optional.empty();
}
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Fri Nov 11 16:44:36 2016 +0100
@@ -32,6 +32,7 @@
import java.nio.ByteBuffer;
import java.util.Objects;
import java.util.Optional;
+import java.util.stream.Stream;
/**
@@ -44,6 +45,11 @@
* module. A module reader is also intended to be used by {@code ClassLoader}
* implementations that load classes and resources from modules.
*
+ * A resource in a module is identified by a name that is a
+ * '{@code /}'-separated path string. For example, module {@code java.base} may
+ * have a resource "{@code java/lang/Object.class}" that, by convention, is the
+ * class file for {@code java.lang.Object}.
+ *
* A {@code ModuleReader} is {@linkplain ModuleReference#open open} upon
* creation and is closed by invoking the {@link #close close} method. Failure
* to close a module reader may result in a resource leak. The {@code
@@ -52,8 +58,8 @@
*
*
A {@code ModuleReader} implementation may require permissions to access
* resources in the module. Consequently the {@link #find find}, {@link #open
- * open} and {@link #read read} methods may throw {@code SecurityException} if
- * access is denied by the security manager.
+ * open}, {@link #read read}, and {@link #list list} methods may throw {@code
+ * SecurityException} if access is denied by the security manager.
*
* @see ModuleReference
* @since 9
@@ -84,6 +90,9 @@
* Opens a resource, returning an input stream to read the resource in
* the module.
*
+ * The behavior of the input stream when used after the module reader
+ * is closed is implementation specific and therefore not specified.
+ *
* @implSpec The default implementation invokes the {@link #find(String)
* find} method to get a URI to the resource. If found, then it attempts
* to construct a {@link java.net.URL URL} and open a connection to the
@@ -172,17 +181,37 @@
}
/**
+ * Lists the contents of the module, returning a stream of elements that
+ * are the names of all resources in the module.
+ *
+ * In lazy implementations then an {@code IOException} may be thrown
+ * when using the stream to list the module contents. If this occurs then
+ * the {@code IOException} will be wrapped in an {@link
+ * java.io.UncheckedIOException} and thrown from the method that caused the
+ * access to be attempted. {@code SecurityException} may also be thrown
+ * when using the stream to list the module contents and access is denied
+ * by the security manager.
+ *
+ * The behavior of the stream when used after the module reader is
+ * closed is implementation specific and therefore not specified.
+ *
+ * @return A stream of elements that are the names of all resources
+ * in the module
+ *
+ * @throws IOException
+ * If an I/O error occurs or the module reader is closed
+ * @throws SecurityException
+ * If denied by the security manager
+ */
+ Stream list() throws IOException;
+
+ /**
* Closes the module reader. Once closed then subsequent calls to locate or
- * read a resource will fail by returning {@code Optional.empty()} or
- * throwing {@code IOException}.
+ * read a resource will fail by throwing {@code IOException}.
*
* A module reader is not required to be asynchronously closeable. If a
* thread is reading a resource and another thread invokes the close method,
- * then the second thread may block until the read operation is complete.
- *
- *
The behavior of {@code InputStream}s obtained using the {@link
- * #open(String) open} method and used after the module reader is closed
- * is implementation specific and therefore not specified.
+ * then the second thread may block until the read operation is complete.
*/
@Override
void close() throws IOException;
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReferences.java Fri Nov 11 16:44:36 2016 +0100
@@ -35,6 +35,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.locks.Lock;
@@ -43,14 +44,17 @@
import java.util.function.Supplier;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import java.util.zip.ZipFile;
+import jdk.internal.jmod.JmodFile;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.module.ModulePatcher;
+import jdk.internal.util.jar.VersionedStream;
import sun.net.www.ParseUtil;
@@ -140,6 +144,13 @@
abstract Optional implOpen(String name) throws IOException;
/**
+ * Returns a stream of the names of resources in the module. This
+ * method is invoked by the list method to do the actual work of
+ * creating the stream.
+ */
+ abstract Stream implList() throws IOException;
+
+ /**
* Closes the module reader. This method is invoked by close to do the
* actual work of closing the module reader.
*/
@@ -175,7 +186,21 @@
}
@Override
- public void close() throws IOException {
+ public final Stream list() throws IOException {
+ readLock.lock();
+ try {
+ if (!closed) {
+ return implList();
+ } else {
+ throw new IOException("ModuleReader is closed");
+ }
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public final void close() throws IOException {
writeLock.lock();
try {
if (!closed) {
@@ -241,6 +266,16 @@
}
@Override
+ Stream implList() throws IOException {
+ // take snapshot to avoid async close
+ List names = VersionedStream.stream(jf)
+ .filter(e -> !e.isDirectory())
+ .map(JarEntry::getName)
+ .collect(Collectors.toList());
+ return names.stream();
+ }
+
+ @Override
void implClose() throws IOException {
jf.close();
}
@@ -251,30 +286,31 @@
* A ModuleReader for a JMOD file.
*/
static class JModModuleReader extends SafeCloseModuleReader {
- private final ZipFile zf;
+ private final JmodFile jf;
private final URI uri;
- static ZipFile newZipFile(Path path) {
+ static JmodFile newJmodFile(Path path) {
try {
- return new ZipFile(path.toFile());
+ return new JmodFile(path);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
JModModuleReader(Path path, URI uri) {
- this.zf = newZipFile(path);
+ this.jf = newJmodFile(path);
this.uri = uri;
}
- private ZipEntry getEntry(String name) {
- return zf.getEntry("classes/" + Objects.requireNonNull(name));
+ private JmodFile.Entry getEntry(String name) {
+ Objects.requireNonNull(name);
+ return jf.getEntry(JmodFile.Section.CLASSES, name);
}
@Override
Optional implFind(String name) {
- ZipEntry ze = getEntry(name);
- if (ze != null) {
+ JmodFile.Entry je = getEntry(name);
+ if (je != null) {
String encodedPath = ParseUtil.encodePath(name, false);
String uris = "jmod:" + uri + "!/" + encodedPath;
return Optional.of(URI.create(uris));
@@ -285,17 +321,27 @@
@Override
Optional implOpen(String name) throws IOException {
- ZipEntry ze = getEntry(name);
- if (ze != null) {
- return Optional.of(zf.getInputStream(ze));
+ JmodFile.Entry je = getEntry(name);
+ if (je != null) {
+ return Optional.of(jf.getInputStream(je));
} else {
return Optional.empty();
}
}
@Override
+ Stream implList() throws IOException {
+ // take snapshot to avoid async close
+ List names = jf.stream()
+ .filter(e -> e.section() == JmodFile.Section.CLASSES)
+ .map(JmodFile.Entry::name)
+ .collect(Collectors.toList());
+ return names.stream();
+ }
+
+ @Override
void implClose() throws IOException {
- zf.close();
+ jf.close();
}
}
@@ -378,6 +424,17 @@
}
@Override
+ public Stream list() throws IOException {
+ ensureOpen();
+ // sym links not followed
+ return Files.find(dir, Integer.MAX_VALUE,
+ (path, attrs) -> attrs.isRegularFile())
+ .map(f -> dir.relativize(f)
+ .toString()
+ .replace(File.separatorChar, '/'));
+ }
+
+ @Override
public void close() {
closed = true;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Fri Nov 11 16:44:36 2016 +0100
@@ -32,14 +32,21 @@
import java.net.URI;
import java.net.URLConnection;
import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
import java.util.Collections;
+import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
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.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
@@ -62,6 +69,8 @@
class SystemModuleFinder implements ModuleFinder {
+ private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
+
private static final PerfCounter initTime
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.initTime");
private static final PerfCounter moduleCount
@@ -73,8 +82,6 @@
// ImageReader used to access all modules in the image
private static final ImageReader imageReader;
- private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
-
// the set of modules in the run-time image
private static final Set modules;
@@ -170,8 +177,7 @@
HashSupplier hash)
{
String mn = md.name();
-
- URI uri = jnua.create("jrt", "/".concat(mn));
+ URI uri = JNUA.create("jrt", "/".concat(mn));
Supplier readerSupplier = new Supplier<>() {
@Override
@@ -332,10 +338,101 @@
}
@Override
+ public Stream list() throws IOException {
+ if (closed)
+ throw new IOException("ModuleReader is closed");
+
+ Spliterator s = new ModuleContentSpliterator(module);
+ return StreamSupport.stream(s, false);
+ }
+
+ @Override
public void close() {
// nothing else to do
closed = true;
}
}
+ /**
+ * A Spliterator for traversing the resources of a module linked into the
+ * run-time image.
+ */
+ static class ModuleContentSpliterator implements Spliterator {
+ final String moduleRoot;
+ final Deque stack;
+ Iterator iterator;
+
+ ModuleContentSpliterator(String module) throws IOException {
+ moduleRoot = "/modules/" + module;
+ stack = new ArrayDeque<>();
+
+ // push the root node to the stack to get started
+ ImageReader.Node dir = imageReader.findNode(moduleRoot);
+ if (dir == null || !dir.isDirectory())
+ throw new IOException(moduleRoot + " not a directory");
+ stack.push(dir);
+ iterator = Collections.emptyIterator();
+ }
+
+ /**
+ * Returns the name of the next non-directory node or {@code null} if
+ * there are no remaining nodes to visit.
+ */
+ private String next() throws IOException {
+ for (;;) {
+ while (iterator.hasNext()) {
+ ImageReader.Node node = iterator.next();
+ String name = node.getName();
+ if (node.isDirectory()) {
+ // build node
+ ImageReader.Node dir = imageReader.findNode(name);
+ assert dir.isDirectory();
+ stack.push(dir);
+ } else {
+ // strip /modules/$MODULE/ prefix
+ return name.substring(moduleRoot.length() + 1);
+ }
+ }
+
+ if (stack.isEmpty()) {
+ return null;
+ } else {
+ ImageReader.Node dir = stack.poll();
+ assert dir.isDirectory();
+ iterator = dir.getChildren().iterator();
+ }
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(Consumer super String> action) {
+ String next;
+ try {
+ next = next();
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ if (next != null) {
+ action.accept(next);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public Spliterator trySplit() {
+ return null;
+ }
+
+ @Override
+ public int characteristics() {
+ return Spliterator.DISTINCT + Spliterator.NONNULL + Spliterator.IMMUTABLE;
+ }
+
+ @Override
+ public long estimateSize() {
+ return Long.MAX_VALUE;
+ }
+ }
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/net/InetAddress.java
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Fri Nov 11 16:44:36 2016 +0100
@@ -201,13 +201,13 @@
* Specify the address family: Internet Protocol, Version 4
* @since 1.4
*/
- static final int IPv4 = 1;
+ @Native static final int IPv4 = 1;
/**
* Specify the address family: Internet Protocol, Version 6
* @since 1.4
*/
- static final int IPv6 = 2;
+ @Native static final int IPv6 = 2;
/* Specify address family preference */
static transient final int preferIPv6Address;
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/net/URLClassLoader.java
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Fri Nov 11 16:44:36 2016 +0100
@@ -110,19 +110,19 @@
if (security != null) {
security.checkCreateClassLoader();
}
- ucp = new URLClassPath(urls);
+ this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
}
- URLClassLoader(URL[] urls, ClassLoader parent,
+ URLClassLoader(String name, URL[] urls, ClassLoader parent,
AccessControlContext acc) {
- super(parent);
+ super(name, parent);
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
- ucp = new URLClassPath(urls);
+ this.ucp = new URLClassPath(urls);
this.acc = acc;
}
@@ -154,7 +154,7 @@
if (security != null) {
security.checkCreateClassLoader();
}
- ucp = new URLClassPath(urls);
+ this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
}
@@ -165,7 +165,7 @@
if (security != null) {
security.checkCreateClassLoader();
}
- ucp = new URLClassPath(urls);
+ this.ucp = new URLClassPath(urls);
this.acc = acc;
}
@@ -198,8 +198,76 @@
if (security != null) {
security.checkCreateClassLoader();
}
- ucp = new URLClassPath(urls, factory);
- acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, factory);
+ this.acc = AccessController.getContext();
+ }
+
+
+ /**
+ * Constructs a new named {@code URLClassLoader} for the specified URLs.
+ * The URLs will be searched in the order specified for classes
+ * and resources after first searching in the specified parent class loader.
+ * Any URL that ends with a '/' is assumed to refer to a directory.
+ * Otherwise, the URL is assumed to refer to a JAR file which will be
+ * downloaded and opened as needed.
+ *
+ * @param name class loader name; or {@code null} if not named
+ * @param urls the URLs from which to load classes and resources
+ * @param parent the parent class loader for delegation
+ *
+ * @throws IllegalArgumentException if the given name is empty.
+ * @throws NullPointerException if {@code urls} is {@code null}.
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@link SecurityManager#checkCreateClassLoader()} method doesn't
+ * allow creation of a class loader.
+ *
+ * @since 9
+ */
+ public URLClassLoader(String name,
+ URL[] urls,
+ ClassLoader parent) {
+ super(name, parent);
+ // this is to make the stack depth consistent with 1.1
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ this.ucp = new URLClassPath(urls);
+ this.acc = AccessController.getContext();
+ }
+
+ /**
+ * Constructs a new named {@code URLClassLoader} for the specified URLs,
+ * parent class loader, and URLStreamHandlerFactory.
+ * The parent argument will be used as the parent class loader for delegation.
+ * The factory argument will be used as the stream handler factory to
+ * obtain protocol handlers when creating new jar URLs.
+ *
+ * @param name class loader name; or {@code null} if not named
+ * @param urls the URLs from which to load classes and resources
+ * @param parent the parent class loader for delegation
+ * @param factory the URLStreamHandlerFactory to use when creating URLs
+ *
+ * @throws IllegalArgumentException if the given name is empty.
+ * @throws NullPointerException if {@code urls} is {@code null}.
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkCreateClassLoader} method doesn't allow
+ * creation of a class loader.
+ *
+ * @since 9
+ */
+ public URLClassLoader(String name, URL[] urls, ClassLoader parent,
+ URLStreamHandlerFactory factory) {
+ super(name, parent);
+ // this is to make the stack depth consistent with 1.1
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ this.ucp = new URLClassPath(urls, factory);
+ this.acc = AccessController.getContext();
}
/* A map (used as a set) to keep track of closeable local resources
@@ -735,7 +803,7 @@
URLClassLoader ucl = AccessController.doPrivileged(
new PrivilegedAction<>() {
public URLClassLoader run() {
- return new FactoryURLClassLoader(urls, parent, acc);
+ return new FactoryURLClassLoader(null, urls, parent, acc);
}
});
return ucl;
@@ -785,9 +853,9 @@
ClassLoader.registerAsParallelCapable();
}
- FactoryURLClassLoader(URL[] urls, ClassLoader parent,
+ FactoryURLClassLoader(String name, URL[] urls, ClassLoader parent,
AccessControlContext acc) {
- super(urls, parent, acc);
+ super(name, urls, parent, acc);
}
FactoryURLClassLoader(URL[] urls, AccessControlContext acc) {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java
--- a/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/nio/file/TempFileHelper.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,8 +55,8 @@
private static final SecureRandom random = new SecureRandom();
private static Path generatePath(String prefix, String suffix, Path dir) {
long n = random.nextLong();
- n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
- Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+ String s = prefix + Long.toUnsignedString(n) + suffix;
+ Path name = dir.getFileSystem().getPath(s);
// the generated name should be a simple file name
if (name.getParent() != null)
throw new IllegalArgumentException("Invalid prefix or suffix");
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java
--- a/jdk/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java Fri Nov 11 16:44:36 2016 +0100
@@ -26,6 +26,7 @@
package java.security;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.Objects;
/**
* The {@code AlgorithmParameterGenerator} class is used to generate a
@@ -153,16 +154,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new AlgorithmParameterGenerator object.
+ * @return the new {@code AlgorithmParameterGenerator} object
*
- * @exception NoSuchAlgorithmException if no Provider supports an
- * AlgorithmParameterGeneratorSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports an
+ * {@code AlgorithmParameterGeneratorSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameterGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
try {
Object[] objs = Security.getImpl(algorithm,
"AlgorithmParameterGenerator",
@@ -197,17 +201,20 @@
*
* @param provider the string name of the Provider.
*
- * @return the new AlgorithmParameterGenerator object.
+ * @return the new {@code AlgorithmParameterGenerator} object
*
- * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if an
+ * {@code AlgorithmParameterGeneratorSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
@@ -215,6 +222,7 @@
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm,
@@ -241,15 +249,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @param provider the Provider object.
+ * @param provider the {@code Provider} object.
*
- * @return the new AlgorithmParameterGenerator object.
+ * @return the new {@code AlgorithmParameterGenerator} object
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if an
+ * {@code AlgorithmParameterGeneratorSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -259,6 +271,7 @@
Provider provider)
throws NoSuchAlgorithmException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/AlgorithmParameters.java
--- a/jdk/src/java.base/share/classes/java/security/AlgorithmParameters.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/AlgorithmParameters.java Fri Nov 11 16:44:36 2016 +0100
@@ -28,6 +28,7 @@
import java.io.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
+import java.util.Objects;
/**
* This class is used as an opaque representation of cryptographic parameters.
@@ -140,16 +141,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new parameter object.
+ * @return the new parameter object
*
- * @exception NoSuchAlgorithmException if no Provider supports an
- * AlgorithmParametersSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports an
+ * {@code AlgorithmParametersSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameters getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
try {
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
(String)null);
@@ -184,17 +188,19 @@
*
* @param provider the name of the provider.
*
- * @return the new parameter object.
+ * @return the new parameter object
*
- * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if an {@code AlgorithmParametersSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
@@ -202,6 +208,7 @@
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
@@ -231,13 +238,16 @@
*
* @param provider the name of the provider.
*
- * @return the new parameter object.
+ * @return the new parameter object
+ *
+ * @throws IllegalArgumentException if the provider is {@code null}
*
- * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if an
+ * {@code AlgorithmParameterGeneratorSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -247,6 +257,7 @@
Provider provider)
throws NoSuchAlgorithmException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/KeyFactory.java
--- a/jdk/src/java.base/share/classes/java/security/KeyFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/KeyFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -167,16 +167,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new KeyFactory object.
+ * @return the new {@code KeyFactory} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * KeyFactorySpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code KeyFactorySpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
return new KeyFactory(algorithm);
}
@@ -200,22 +203,25 @@
*
* @param provider the name of the provider.
*
- * @return the new KeyFactory object.
+ * @return the new {@code KeyFactory} object
*
- * @exception NoSuchAlgorithmException if a KeyFactorySpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyFactory getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyFactory",
KeyFactorySpi.class, algorithm, provider);
return new KeyFactory((KeyFactorySpi)instance.impl,
@@ -239,13 +245,16 @@
*
* @param provider the provider.
*
- * @return the new KeyFactory object.
+ * @return the new {@code KeyFactory} object
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a KeyFactorySpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -253,6 +262,7 @@
*/
public static KeyFactory getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyFactory",
KeyFactorySpi.class, algorithm, provider);
return new KeyFactory((KeyFactorySpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java
--- a/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/KeyPairGenerator.java Fri Nov 11 16:44:36 2016 +0100
@@ -209,16 +209,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new KeyPairGenerator object.
+ * @return the new {@code KeyPairGenerator} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * KeyPairGeneratorSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code KeyPairGeneratorSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyPairGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
List list =
GetInstance.getServices("KeyPairGenerator", algorithm);
Iterator t = list.iterator();
@@ -267,23 +270,26 @@
*
* @param provider the string name of the provider.
*
- * @return the new KeyPairGenerator object.
+ * @return the new {@code KeyPairGenerator} object
*
- * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code KeyPairGeneratorSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyPairGenerator getInstance(String algorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyPairGenerator",
KeyPairGeneratorSpi.class, algorithm, provider);
return getInstance(instance, algorithm);
@@ -306,13 +312,16 @@
*
* @param provider the provider.
*
- * @return the new KeyPairGenerator object.
+ * @return the new {@code KeyPairGenerator} object
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code KeyPairGeneratorSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -320,6 +329,7 @@
*/
public static KeyPairGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyPairGenerator",
KeyPairGeneratorSpi.class, algorithm, provider);
return getInstance(instance, algorithm);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/KeyStore.java
--- a/jdk/src/java.base/share/classes/java/security/KeyStore.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/KeyStore.java Fri Nov 11 16:44:36 2016 +0100
@@ -26,7 +26,6 @@
package java.security;
import java.io.*;
-import java.net.URI;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
@@ -855,17 +854,20 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard keystore types.
*
- * @return a keystore object of the specified type.
+ * @return a keystore object of the specified type
*
- * @exception KeyStoreException if no Provider supports a
- * KeyStoreSpi implementation for the
- * specified type.
+ * @throws KeyStoreException if no {@code Provider} supports a
+ * {@code KeyStoreSpi} implementation for the
+ * specified type
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see Provider
*/
public static KeyStore getInstance(String type)
throws KeyStoreException
{
+ Objects.requireNonNull(type, "null type name");
try {
Object[] objs = Security.getImpl(type, "KeyStore", (String)null);
return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type);
@@ -895,23 +897,26 @@
*
* @param provider the name of the provider.
*
- * @return a keystore object of the specified type.
+ * @return a keystore object of the specified type
*
- * @exception KeyStoreException if a KeyStoreSpi
- * implementation for the specified type is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws KeyStoreException if a {@code KeyStoreSpi}
+ * implementation for the specified type is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see Provider
*/
public static KeyStore getInstance(String type, String provider)
throws KeyStoreException, NoSuchProviderException
{
+ Objects.requireNonNull(type, "null type name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
try {
@@ -938,13 +943,16 @@
*
* @param provider the provider.
*
- * @return a keystore object of the specified type.
+ * @return a keystore object of the specified type
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
- * @exception KeyStoreException if KeyStoreSpi
- * implementation for the specified type is not available
- * from the specified Provider object.
+ * @throws KeyStoreException if {@code KeyStoreSpi}
+ * implementation for the specified type is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see Provider
*
@@ -953,6 +961,7 @@
public static KeyStore getInstance(String type, Provider provider)
throws KeyStoreException
{
+ Objects.requireNonNull(type, "null type name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
try {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/MessageDigest.java
--- a/jdk/src/java.base/share/classes/java/security/MessageDigest.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/MessageDigest.java Fri Nov 11 16:44:36 2016 +0100
@@ -26,13 +26,8 @@
package java.security;
import java.util.*;
-import java.lang.*;
-import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
-import java.security.InvalidKeyException;
import java.nio.ByteBuffer;
import sun.security.util.Debug;
@@ -163,16 +158,20 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return a Message Digest object that implements the specified algorithm.
+ * @return a {@code MessageDigest} object that implements the
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * MessageDigestSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code MessageDigestSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
try {
MessageDigest md;
Object[] objs = Security.getImpl(algorithm, "MessageDigest",
@@ -216,23 +215,27 @@
*
* @param provider the name of the provider.
*
- * @return a MessageDigest object that implements the specified algorithm.
+ * @return a {@code MessageDigest} object that implements the
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if a MessageDigestSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
@@ -265,13 +268,17 @@
*
* @param provider the provider.
*
- * @return a MessageDigest object that implements the specified algorithm.
+ * @return a {@code MessageDigest} object that implements the
+ * specified algorithm
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a MessageDigestSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -281,6 +288,7 @@
Provider provider)
throws NoSuchAlgorithmException
{
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/Policy.java
--- a/jdk/src/java.base/share/classes/java/security/Policy.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/Policy.java Fri Nov 11 16:44:36 2016 +0100
@@ -29,6 +29,7 @@
import java.util.Enumeration;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.Objects;
import sun.security.jca.GetInstance;
import sun.security.util.Debug;
import sun.security.util.SecurityConstants;
@@ -372,26 +373,26 @@
*
* @param params parameters for the Policy, which may be null.
*
- * @return the new Policy object.
+ * @return the new {@code Policy} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Policy instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified parameters
+ * are not understood by the {@code PolicySpi} implementation
+ * from the selected {@code Provider}
*
- * @exception IllegalArgumentException if the specified parameters
- * are not understood by the PolicySpi implementation
- * from the selected Provider.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports
+ * a {@code PolicySpi} implementation for the specified type
*
- * @exception NoSuchAlgorithmException if no Provider supports a PolicySpi
- * implementation for the specified type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Policy} instance for the specified type.
*
* @see Provider
* @since 1.6
*/
public static Policy getInstance(String type, Policy.Parameters params)
throws NoSuchAlgorithmException {
-
+ Objects.requireNonNull(type, "null type name");
checkPermission(type);
try {
GetInstance.Instance instance = GetInstance.getInstance("Policy",
@@ -428,23 +429,24 @@
*
* @param provider the provider.
*
- * @return the new Policy object.
+ * @return the new {@code Policy} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Policy instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified provider
+ * is {@code null} or empty, or if the specified parameters are
+ * not understood by the {@code PolicySpi} implementation from
+ * the specified provider
*
- * @exception IllegalArgumentException if the specified provider
- * is null or empty,
- * or if the specified parameters are not understood by
- * the PolicySpi implementation from the specified provider.
+ * @throws NoSuchAlgorithmException if the specified provider does not
+ * support a {@code PolicySpi} implementation for the specified
+ * type
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
- * @exception NoSuchAlgorithmException if the specified provider does not
- * support a PolicySpi implementation for the specified type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Policy} instance for the specified type
*
* @see Provider
* @since 1.6
@@ -454,6 +456,7 @@
String provider)
throws NoSuchProviderException, NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
if (provider == null || provider.length() == 0) {
throw new IllegalArgumentException("missing provider");
}
@@ -492,19 +495,21 @@
*
* @param provider the Provider.
*
- * @return the new Policy object.
+ * @return the new {@code Policy} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Policy instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified {@code Provider}
+ * is {@code null}, or if the specified parameters are not
+ * understood by the {@code PolicySpi} implementation from the
+ * specified {@code Provider}
*
- * @exception IllegalArgumentException if the specified Provider is null,
- * or if the specified parameters are not understood by
- * the PolicySpi implementation from the specified Provider.
+ * @throws NoSuchAlgorithmException if the specified {@code Provider}
+ * does not support a {@code PolicySpi} implementation for
+ * the specified type
*
- * @exception NoSuchAlgorithmException if the specified Provider does not
- * support a PolicySpi implementation for the specified type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Policy} instance for the specified type
*
* @see Provider
* @since 1.6
@@ -514,6 +519,7 @@
Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
if (provider == null) {
throw new IllegalArgumentException("missing provider");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/SecureClassLoader.java
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Fri Nov 11 16:44:36 2016 +0100
@@ -25,8 +25,6 @@
package java.security;
-import java.net.URL;
-import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@@ -114,6 +112,30 @@
}
/**
+ * Creates a new {@code SecureClassLoader} of the specified name and
+ * using the specified parent class loader for delegation.
+ *
+ * @param name class loader name; or {@code null} if not named
+ * @param parent the parent class loader
+ *
+ * @throws IllegalArgumentException if the given name is empty.
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@link SecurityManager#checkCreateClassLoader()} method
+ * doesn't allow creation of a class loader.
+ *
+ * @since 9
+ */
+ protected SecureClassLoader(String name, ClassLoader parent) {
+ super(name, parent);
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkCreateClassLoader();
+ }
+ initialized = true;
+ }
+
+ /**
* Converts an array of bytes into an instance of class Class,
* with an optional CodeSource. Before the
* class can be used it must be resolved.
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/SecureRandom.java
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java Fri Nov 11 16:44:36 2016 +0100
@@ -303,11 +303,13 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard RNG algorithm names.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * {@code SecureRandomSpi} implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code SecureRandomSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -315,6 +317,7 @@
*/
public static SecureRandom getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("SecureRandom",
SecureRandomSpi.class, algorithm);
return new SecureRandom((SecureRandomSpi)instance.impl,
@@ -341,17 +344,19 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
+ *
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
* @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
* implementation for the specified algorithm is not
- * available from the specified provider.
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @throws IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -359,6 +364,7 @@
*/
public static SecureRandom getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("SecureRandom",
SecureRandomSpi.class, algorithm, provider);
return new SecureRandom((SecureRandomSpi)instance.impl,
@@ -382,13 +388,16 @@
*
* @param provider the provider.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
+ *
+ * @throws IllegalArgumentException if the specified provider is
+ * {@code null}
*
* @throws NoSuchAlgorithmException if a {@code SecureRandomSpi}
* implementation for the specified algorithm is not available
- * from the specified {@code Provider} object.
+ * from the specified {@code Provider} object
*
- * @throws IllegalArgumentException if the specified provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -396,6 +405,7 @@
*/
public static SecureRandom getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("SecureRandom",
SecureRandomSpi.class, algorithm, provider);
return new SecureRandom((SecureRandomSpi)instance.impl,
@@ -433,13 +443,16 @@
* @param params the {@code SecureRandomParameters}
* the newly created {@code SecureRandom} object must support.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
+ *
+ * @throws IllegalArgumentException if the specified params is
+ * {@code null}
*
* @throws NoSuchAlgorithmException if no Provider supports a
* {@code SecureRandomSpi} implementation for the specified
- * algorithm and parameters.
+ * algorithm and parameters
*
- * @throws IllegalArgumentException if the specified params is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -448,6 +461,7 @@
public static SecureRandom getInstance(
String algorithm, SecureRandomParameters params)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (params == null) {
throw new IllegalArgumentException("params cannot be null");
}
@@ -481,17 +495,19 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
+ *
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty, or params is {@code null}
*
* @throws NoSuchAlgorithmException if the specified provider does not
* support a {@code SecureRandomSpi} implementation for the
- * specified algorithm and parameters.
+ * specified algorithm and parameters
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @throws IllegalArgumentException if the provider name is null
- * or empty, or params is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -500,6 +516,7 @@
public static SecureRandom getInstance(String algorithm,
SecureRandomParameters params, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (params == null) {
throw new IllegalArgumentException("params cannot be null");
}
@@ -531,14 +548,16 @@
*
* @param provider the provider.
*
- * @return the new {@code SecureRandom} object.
+ * @return the new {@code SecureRandom} object
+ *
+ * @throws IllegalArgumentException if the specified provider or params
+ * is {@code null}
*
* @throws NoSuchAlgorithmException if the specified provider does not
* support a {@code SecureRandomSpi} implementation for the
- * specified algorithm and parameters.
+ * specified algorithm and parameters
*
- * @throws IllegalArgumentException if the specified provider or params
- * is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -547,6 +566,7 @@
public static SecureRandom getInstance(String algorithm,
SecureRandomParameters params, Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (params == null) {
throw new IllegalArgumentException("params cannot be null");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/Signature.java
--- a/jdk/src/java.base/share/classes/java/security/Signature.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/Signature.java Fri Nov 11 16:44:36 2016 +0100
@@ -213,16 +213,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new Signature object.
+ * @return the new {@code Signature} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * Signature implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code Signature} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static Signature getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
List list;
if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
list = GetInstance.getServices(rsaIds);
@@ -335,22 +338,25 @@
*
* @param provider the name of the provider.
*
- * @return the new Signature object.
+ * @return the new {@code Signature} object
*
- * @exception NoSuchAlgorithmException if a SignatureSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static Signature getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
// exception compatibility with existing code
if ((provider == null) || (provider.length() == 0)) {
@@ -385,13 +391,15 @@
*
* @param provider the provider.
*
- * @return the new Signature object.
+ * @return the new {@code Signature} object
+ *
+ * @throws IllegalArgumentException if the provider is {@code null}
*
- * @exception NoSuchAlgorithmException if a SignatureSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code SignatureSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the provider is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
@@ -399,6 +407,7 @@
*/
public static Signature getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) {
// exception compatibility with existing code
if (provider == null) {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/cert/CertPathBuilder.java
--- a/jdk/src/java.base/share/classes/java/security/cert/CertPathBuilder.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/cert/CertPathBuilder.java Fri Nov 11 16:44:36 2016 +0100
@@ -32,7 +32,7 @@
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
-import sun.security.util.Debug;
+import java.util.Objects;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
@@ -157,16 +157,19 @@
* for information about standard algorithm names.
*
* @return a {@code CertPathBuilder} object that implements the
- * specified algorithm.
+ * specified algorithm
*
- * @throws NoSuchAlgorithmException if no Provider supports a
- * CertPathBuilderSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code CertPathBuilderSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
@@ -194,22 +197,25 @@
* @param provider the name of the provider.
*
* @return a {@code CertPathBuilder} object that implements the
- * specified algorithm.
+ * specified algorithm
*
- * @throws NoSuchAlgorithmException if a CertPathBuilderSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null} or empty
+ *
+ * @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm, provider);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
@@ -234,19 +240,22 @@
* @param provider the provider.
*
* @return a {@code CertPathBuilder} object that implements the
- * specified algorithm.
+ * specified algorithm
+ *
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a CertPathBuilderSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm, provider);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/cert/CertPathValidator.java
--- a/jdk/src/java.base/share/classes/java/security/cert/CertPathValidator.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/cert/CertPathValidator.java Fri Nov 11 16:44:36 2016 +0100
@@ -32,7 +32,7 @@
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
-import sun.security.util.Debug;
+import java.util.Objects;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
@@ -158,16 +158,19 @@
* for information about standard algorithm names.
*
* @return a {@code CertPathValidator} object that implements the
- * specified algorithm.
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * CertPathValidatorSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code CertPathValidatorSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
@@ -195,23 +198,26 @@
* @param provider the name of the provider.
*
* @return a {@code CertPathValidator} object that implements the
- * specified algorithm.
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null} or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code CertPathValidatorSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm, provider);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
@@ -236,19 +242,22 @@
* @param provider the provider.
*
* @return a {@code CertPathValidator} object that implements the
- * specified algorithm.
+ * specified algorithm
+ *
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a CertPathValidatorSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code CertPathValidatorSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified Provider object
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm, provider);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/cert/CertStore.java
--- a/jdk/src/java.base/share/classes/java/security/cert/CertStore.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/cert/CertStore.java Fri Nov 11 16:44:36 2016 +0100
@@ -33,6 +33,7 @@
import java.security.Provider;
import java.security.Security;
import java.util.Collection;
+import java.util.Objects;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
@@ -218,20 +219,23 @@
* @param params the initialization parameters (may be {@code null}).
*
* @return a {@code CertStore} object that implements the specified
- * {@code CertStore} type.
- *
- * @throws NoSuchAlgorithmException if no Provider supports a
- * CertStoreSpi implementation for the specified type.
+ * {@code CertStore} type
*
* @throws InvalidAlgorithmParameterException if the specified
- * initialization parameters are inappropriate for this
- * {@code CertStore}.
+ * initialization parameters are inappropriate for this
+ * {@code CertStore}
+ *
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code CertStoreSpi} implementation for the specified type
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*/
public static CertStore getInstance(String type, CertStoreParameters params)
throws InvalidAlgorithmParameterException,
NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertStore",
CertStoreSpi.class, type, params);
@@ -243,7 +247,8 @@
}
private static CertStore handleException(NoSuchAlgorithmException e)
- throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException {
Throwable cause = e.getCause();
if (cause instanceof InvalidAlgorithmParameterException) {
throw (InvalidAlgorithmParameterException)cause;
@@ -280,21 +285,23 @@
* @param provider the name of the provider.
*
* @return a {@code CertStore} object that implements the
- * specified type.
+ * specified type
*
- * @throws NoSuchAlgorithmException if a CertStoreSpi
- * implementation for the specified type is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null} or empty
*
* @throws InvalidAlgorithmParameterException if the specified
- * initialization parameters are inappropriate for this
- * {@code CertStore}.
+ * initialization parameters are inappropriate for this
+ * {@code CertStore}
+ *
+ * @throws NoSuchAlgorithmException if a {@code CertStoreSpi}
+ * implementation for the specified type is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null or empty.
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*/
@@ -302,6 +309,7 @@
CertStoreParameters params, String provider)
throws InvalidAlgorithmParameterException,
NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertStore",
CertStoreSpi.class, type, params, provider);
@@ -338,24 +346,27 @@
* @param provider the provider.
*
* @return a {@code CertStore} object that implements the
- * specified type.
+ * specified type
*
- * @exception NoSuchAlgorithmException if a CertStoreSpi
- * implementation for the specified type is not available
- * from the specified Provider object.
+ * @throws IllegalArgumentException if the {@code provider} is
+ * null
*
* @throws InvalidAlgorithmParameterException if the specified
- * initialization parameters are inappropriate for this
- * {@code CertStore}
+ * initialization parameters are inappropriate for this
+ * {@code CertStore}
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null.
+ * @throws NoSuchAlgorithmException if a {@code CertStoreSpi}
+ * implementation for the specified type is not available
+ * from the specified Provider object
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*/
public static CertStore getInstance(String type, CertStoreParameters params,
Provider provider) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertStore",
CertStoreSpi.class, type, params, provider);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/security/cert/CertificateFactory.java
--- a/jdk/src/java.base/share/classes/java/security/cert/CertificateFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/security/cert/CertificateFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -29,10 +29,9 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.security.Provider;
import java.security.Security;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@@ -177,16 +176,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard certificate types.
*
- * @return a certificate factory object for the specified type.
+ * @return a certificate factory object for the specified type
*
- * @exception CertificateException if no Provider supports a
- * CertificateFactorySpi implementation for the
- * specified type.
+ * @throws CertificateException if no {@code Provider} supports a
+ * {@code CertificateFactorySpi} implementation for the
+ * specified type
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*/
public static final CertificateFactory getInstance(String type)
throws CertificateException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertificateFactory",
CertificateFactorySpi.class, type);
@@ -217,23 +219,26 @@
*
* @param provider the name of the provider.
*
- * @return a certificate factory object for the specified type.
+ * @return a certificate factory object for the specified type
*
- * @exception CertificateException if a CertificateFactorySpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws CertificateException if a {@code CertificateFactorySpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
*
- * @exception IllegalArgumentException if the provider name is null
- * or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*/
public static final CertificateFactory getInstance(String type,
String provider) throws CertificateException,
NoSuchProviderException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertificateFactory",
CertificateFactorySpi.class, type, provider);
@@ -260,14 +265,16 @@
* for information about standard certificate types.
* @param provider the provider.
*
- * @return a certificate factory object for the specified type.
+ * @return a certificate factory object for the specified type
*
- * @exception CertificateException if a CertificateFactorySpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws CertificateException if a {@code CertificateFactorySpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the {@code provider} is
- * null.
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null}
+ *
+ * @throws NullPointerException if {@code type} is {@code null}
*
* @see java.security.Provider
*
@@ -275,6 +282,7 @@
*/
public static final CertificateFactory getInstance(String type,
Provider provider) throws CertificateException {
+ Objects.requireNonNull(type, "null type name");
try {
Instance instance = GetInstance.getInstance("CertificateFactory",
CertificateFactorySpi.class, type, provider);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/ImmutableCollections.java
--- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java Fri Nov 11 16:44:36 2016 +0100
@@ -53,7 +53,8 @@
*/
static final int SALT;
static {
- SALT = new Random().nextInt();
+ long nt = System.nanoTime();
+ SALT = (int)((nt >>> 32) ^ nt);
}
/** No instances. */
@@ -63,7 +64,7 @@
* The reciprocal of load factor. Given a number of elements
* to store, multiply by this factor to get the table size.
*/
- static final double EXPAND_FACTOR = 2.0;
+ static final int EXPAND_FACTOR = 2;
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
@@ -84,7 +85,14 @@
}
static final class List0 extends AbstractImmutableList {
- List0() { }
+ private static final List0> INSTANCE = new List0<>();
+
+ @SuppressWarnings("unchecked")
+ static List0 instance() {
+ return (List0) INSTANCE;
+ }
+
+ private List0() { }
@Override
public int size() {
@@ -214,7 +222,14 @@
}
static final class Set0 extends AbstractImmutableSet {
- Set0() { }
+ private static final Set0> INSTANCE = new Set0<>();
+
+ @SuppressWarnings("unchecked")
+ static Set0 instance() {
+ return (Set0) INSTANCE;
+ }
+
+ private Set0() { }
@Override
public int size() {
@@ -351,7 +366,7 @@
SetN(E... input) {
size = input.length; // implicit nullcheck of input
- elements = (E[])new Object[(int)Math.ceil(EXPAND_FACTOR * input.length)];
+ elements = (E[])new Object[EXPAND_FACTOR * input.length];
for (int i = 0; i < input.length; i++) {
E e = Objects.requireNonNull(input[i]);
int idx = probe(e);
@@ -450,7 +465,14 @@
}
static final class Map0 extends AbstractImmutableMap {
- Map0() { }
+ private static final Map0,?> INSTANCE = new Map0<>();
+
+ @SuppressWarnings("unchecked")
+ static Map0 instance() {
+ return (Map0) INSTANCE;
+ }
+
+ private Map0() { }
@Override
public Set> entrySet() {
@@ -529,7 +551,7 @@
}
size = input.length >> 1;
- int len = (int)Math.ceil(EXPAND_FACTOR * input.length);
+ int len = EXPAND_FACTOR * input.length;
len = (len + 1) & ~1; // ensure table is even length
table = new Object[len];
@@ -789,7 +811,7 @@
return Set.of(array);
case IMM_MAP:
if (array.length == 0) {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
} else if (array.length == 2) {
return new ImmutableCollections.Map1<>(array[0], array[1]);
} else {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/List.java
--- a/jdk/src/java.base/share/classes/java/util/List.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/List.java Fri Nov 11 16:44:36 2016 +0100
@@ -786,7 +786,7 @@
* @since 9
*/
static List of() {
- return new ImmutableCollections.List0<>();
+ return ImmutableCollections.List0.instance();
}
/**
@@ -1030,7 +1030,7 @@
Objects.requireNonNull(elements);
switch (elements.length) {
case 0:
- return new ImmutableCollections.List0<>();
+ return ImmutableCollections.List0.instance();
case 1:
return new ImmutableCollections.List1<>(elements[0]);
case 2:
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/Map.java
--- a/jdk/src/java.base/share/classes/java/util/Map.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Map.java Fri Nov 11 16:44:36 2016 +0100
@@ -1286,7 +1286,7 @@
* @since 9
*/
static Map of() {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
}
/**
@@ -1604,7 +1604,7 @@
static Map ofEntries(Entry extends K, ? extends V>... entries) {
Objects.requireNonNull(entries);
if (entries.length == 0) {
- return new ImmutableCollections.Map0<>();
+ return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
return new ImmutableCollections.Map1<>(entries[0].getKey(),
entries[0].getValue());
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/Scanner.java
--- a/jdk/src/java.base/share/classes/java/util/Scanner.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Scanner.java Fri Nov 11 16:44:36 2016 +0100
@@ -1267,6 +1267,9 @@
// The next operation should occur in the specified radix but
// the default is left untouched.
private void setRadix(int radix) {
+ if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX))
+ throw new IllegalArgumentException("radix:"+radix);
+
if (this.radix != radix) {
// Force rebuilding and recompilation of radix dependent patterns
integerPattern = null;
@@ -1811,10 +1814,15 @@
* interpreted as a byte value in the specified radix using the
* {@link #nextByte} method. The scanner does not advance past any input.
*
+ * If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as a byte value
* @return true if and only if this scanner's next token is a valid
* byte value
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public boolean hasNextByte(int radix) {
setRadix(radix);
@@ -1869,6 +1877,10 @@
* {@link Byte#parseByte(String, int) Byte.parseByte} with the
* specified radix.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as a byte value
* @return the {@code byte} scanned from the input
* @throws InputMismatchException
@@ -1876,6 +1888,7 @@
* regular expression, or is out of range
* @throws NoSuchElementException if input is exhausted
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public byte nextByte(int radix) {
// Check cached result
@@ -1917,10 +1930,15 @@
* interpreted as a short value in the specified radix using the
* {@link #nextShort} method. The scanner does not advance past any input.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as a short value
* @return true if and only if this scanner's next token is a valid
* short value in the specified radix
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public boolean hasNextShort(int radix) {
setRadix(radix);
@@ -1975,6 +1993,10 @@
* {@link Short#parseShort(String, int) Short.parseShort} with the
* specified radix.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as a short value
* @return the {@code short} scanned from the input
* @throws InputMismatchException
@@ -1982,6 +2004,7 @@
* regular expression, or is out of range
* @throws NoSuchElementException if input is exhausted
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public short nextShort(int radix) {
// Check cached result
@@ -2023,10 +2046,15 @@
* interpreted as an int value in the specified radix using the
* {@link #nextInt} method. The scanner does not advance past any input.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as an int value
* @return true if and only if this scanner's next token is a valid
* int value
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public boolean hasNextInt(int radix) {
setRadix(radix);
@@ -2105,6 +2133,10 @@
* {@link Integer#parseInt(String, int) Integer.parseInt} with the
* specified radix.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as an int value
* @return the {@code int} scanned from the input
* @throws InputMismatchException
@@ -2112,6 +2144,7 @@
* regular expression, or is out of range
* @throws NoSuchElementException if input is exhausted
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public int nextInt(int radix) {
// Check cached result
@@ -2153,10 +2186,15 @@
* interpreted as a long value in the specified radix using the
* {@link #nextLong} method. The scanner does not advance past any input.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as a long value
* @return true if and only if this scanner's next token is a valid
* long value
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public boolean hasNextLong(int radix) {
setRadix(radix);
@@ -2211,6 +2249,10 @@
* {@link Long#parseLong(String, int) Long.parseLong} with the
* specified radix.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as an int value
* @return the {@code long} scanned from the input
* @throws InputMismatchException
@@ -2218,6 +2260,7 @@
* regular expression, or is out of range
* @throws NoSuchElementException if input is exhausted
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public long nextLong(int radix) {
// Check cached result
@@ -2450,10 +2493,15 @@
* the {@link #nextBigInteger} method. The scanner does not advance past
* any input.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token as an integer
* @return true if and only if this scanner's next token is a valid
* {@code BigInteger}
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public boolean hasNextBigInteger(int radix) {
setRadix(radix);
@@ -2504,6 +2552,10 @@
* java.math.BigInteger#BigInteger(java.lang.String)
* BigInteger(String, int)} constructor with the specified radix.
*
+ *
If the radix is less than {@link Character#MIN_RADIX Character.MIN_RADIX}
+ * or greater than {@link Character#MAX_RADIX Character.MAX_RADIX}, then an
+ * {@code IllegalArgumentException} is thrown.
+ *
* @param radix the radix used to interpret the token
* @return the {@code BigInteger} scanned from the input
* @throws InputMismatchException
@@ -2511,6 +2563,7 @@
* regular expression, or is out of range
* @throws NoSuchElementException if the input is exhausted
* @throws IllegalStateException if this scanner is closed
+ * @throws IllegalArgumentException if the radix is out of range
*/
public BigInteger nextBigInteger(int radix) {
// Check cached result
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/Set.java
--- a/jdk/src/java.base/share/classes/java/util/Set.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Set.java Fri Nov 11 16:44:36 2016 +0100
@@ -448,7 +448,7 @@
* @since 9
*/
static Set of() {
- return new ImmutableCollections.Set0<>();
+ return ImmutableCollections.Set0.instance();
}
/**
@@ -692,7 +692,7 @@
Objects.requireNonNull(elements);
switch (elements.length) {
case 0:
- return new ImmutableCollections.Set0<>();
+ return ImmutableCollections.Set0.instance();
case 1:
return new ImmutableCollections.Set1<>(elements[0]);
case 2:
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/java/util/stream/Collectors.java
--- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Fri Nov 11 16:44:36 2016 +0100
@@ -508,7 +508,7 @@
* transformation. For example, one could adapt the {@link #toList()}
* collector to always produce an immutable list with:
* {@code
- * List people
+ * List list
* = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList));
* }
*
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/Cipher.java
--- a/jdk/src/java.base/share/classes/javax/crypto/Cipher.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/Cipher.java Fri Nov 11 16:44:36 2016 +0100
@@ -493,21 +493,24 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard transformation names.
*
- * @return a cipher that implements the requested transformation.
+ * @return a cipher that implements the requested transformation
*
- * @exception NoSuchAlgorithmException if {@code transformation}
- * is null, empty, in an invalid format,
- * or if no Provider supports a CipherSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if {@code transformation}
+ * is {@code null}, empty, in an invalid format,
+ * or if no {@code Provider} supports a {@code CipherSpi}
+ * implementation for the specified algorithm
*
- * @exception NoSuchPaddingException if {@code transformation}
- * contains a padding scheme that is not available.
+ * @throws NoSuchPaddingException if {@code transformation}
+ * contains a padding scheme that is not available
*
* @see java.security.Provider
*/
public static final Cipher getInstance(String transformation)
throws NoSuchAlgorithmException, NoSuchPaddingException
{
+ if ((transformation == null) || transformation.equals("")) {
+ throw new NoSuchAlgorithmException("Null or empty transformation");
+ }
List transforms = getTransforms(transformation);
List cipherServices = new ArrayList<>(transforms.size());
for (Transform transform : transforms) {
@@ -570,21 +573,22 @@
*
* @param provider the name of the provider.
*
- * @return a cipher that implements the requested transformation.
+ * @return a cipher that implements the requested transformation
*
- * @exception NoSuchAlgorithmException if {@code transformation}
- * is null, empty, in an invalid format,
- * or if a CipherSpi implementation for the specified algorithm
- * is not available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if {@code transformation}
+ * is {@code null}, empty, in an invalid format,
+ * or if a {@code CipherSpi} implementation for the
+ * specified algorithm is not available from the specified
+ * provider
*
- * @exception NoSuchPaddingException if {@code transformation}
- * contains a padding scheme that is not available.
+ * @throws NoSuchPaddingException if {@code transformation}
+ * contains a padding scheme that is not available
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
* @see java.security.Provider
*/
@@ -593,6 +597,9 @@
throws NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException
{
+ if ((transformation == null) || transformation.equals("")) {
+ throw new NoSuchAlgorithmException("Null or empty transformation");
+ }
if ((provider == null) || (provider.length() == 0)) {
throw new IllegalArgumentException("Missing provider");
}
@@ -622,18 +629,19 @@
*
* @param provider the provider.
*
- * @return a cipher that implements the requested transformation.
+ * @return a cipher that implements the requested transformation
+ *
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null}
*
- * @exception NoSuchAlgorithmException if {@code transformation}
- * is null, empty, in an invalid format,
- * or if a CipherSpi implementation for the specified algorithm
- * is not available from the specified Provider object.
+ * @throws NoSuchAlgorithmException if {@code transformation}
+ * is {@code null}, empty, in an invalid format,
+ * or if a {@code CipherSpi} implementation for the
+ * specified algorithm is not available from the specified
+ * {@code Provider} object
*
- * @exception NoSuchPaddingException if {@code transformation}
- * contains a padding scheme that is not available.
- *
- * @exception IllegalArgumentException if the {@code provider}
- * is null.
+ * @throws NoSuchPaddingException if {@code transformation}
+ * contains a padding scheme that is not available
*
* @see java.security.Provider
*/
@@ -641,6 +649,9 @@
Provider provider)
throws NoSuchAlgorithmException, NoSuchPaddingException
{
+ if ((transformation == null) || transformation.equals("")) {
+ throw new NoSuchAlgorithmException("Null or empty transformation");
+ }
if (provider == null) {
throw new IllegalArgumentException("Missing provider");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/ExemptionMechanism.java
--- a/jdk/src/java.base/share/classes/javax/crypto/ExemptionMechanism.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/ExemptionMechanism.java Fri Nov 11 16:44:36 2016 +0100
@@ -34,6 +34,7 @@
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.Objects;
import sun.security.jca.GetInstance.Instance;
@@ -128,19 +129,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard exemption mechanism names.
*
- * @return the new ExemptionMechanism
object.
+ * @return the new {@code ExemptionMechanism} object
*
- * @exception NullPointerException if algorithm
- * is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports an
+ * {@code ExemptionMechanismSpi} implementation for the
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if no Provider supports an
- * ExemptionMechanismSpi implementation for the
- * specified algorithm.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
@@ -169,26 +170,26 @@
*
* @param provider the name of the provider.
*
- * @return the new ExemptionMechanism
object.
+ * @return the new {@code ExemptionMechanism} object
*
- * @exception NullPointerException if algorithm
- * is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NoSuchAlgorithmException if an ExemptionMechanismSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the provider
- * is null or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm, provider);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
@@ -213,22 +214,22 @@
*
* @param provider the provider.
*
- * @return the new ExemptionMechanism
object.
+ * @return the new {@code ExemptionMechanism} object
*
- * @exception NullPointerException if algorithm
- * is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is null
*
- * @exception NoSuchAlgorithmException if an ExemptionMechanismSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider object}
*
- * @exception IllegalArgumentException if the provider
- * is null.
+ * @exception NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm, provider);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/KeyAgreement.java
--- a/jdk/src/java.base/share/classes/javax/crypto/KeyAgreement.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/KeyAgreement.java Fri Nov 11 16:44:36 2016 +0100
@@ -165,19 +165,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new {@code KeyAgreement} object.
+ * @return the new {@code KeyAgreement} object
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code KeyAgreementSpi} implementation for the
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * KeyAgreementSpi implementation for the
- * specified algorithm.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
List services =
GetInstance.getServices("KeyAgreement", algorithm);
// make sure there is at least one service from a signed provider
@@ -214,26 +214,26 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code KeyAgreement} object.
+ * @return the new {@code KeyAgreement} object
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NoSuchAlgorithmException if a KeyAgreementSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws NoSuchAlgorithmException if a {@code KeyAgreementSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
return new KeyAgreement((KeyAgreementSpi)instance.impl,
@@ -258,22 +258,22 @@
*
* @param provider the provider.
*
- * @return the new {@code KeyAgreement} object.
+ * @return the new {@code KeyAgreement} object
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null}
*
- * @exception NoSuchAlgorithmException if a KeyAgreementSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code KeyAgreementSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified Provider object
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
return new KeyAgreement((KeyAgreementSpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/KeyGenerator.java
--- a/jdk/src/java.base/share/classes/javax/crypto/KeyGenerator.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/KeyGenerator.java Fri Nov 11 16:44:36 2016 +0100
@@ -216,18 +216,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new {@code KeyGenerator} object.
- *
- * @exception NullPointerException if the specified algorithm is null.
+ * @return the new {@code KeyGenerator} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * KeyGeneratorSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code KeyGeneratorSpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
return new KeyGenerator(algorithm);
}
@@ -251,25 +252,26 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code KeyGenerator} object.
+ * @return the new {@code KeyGenerator} object
*
- * @exception NullPointerException if the specified algorithm is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws NoSuchAlgorithmException if a {@code KeyGeneratorSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("KeyGenerator",
KeyGeneratorSpi.class, algorithm, provider);
return new KeyGenerator((KeyGeneratorSpi)instance.impl,
@@ -293,21 +295,22 @@
*
* @param provider the provider.
*
- * @return the new {@code KeyGenerator} object.
+ * @return the new {@code KeyGenerator} object
*
- * @exception NullPointerException if the specified algorithm is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null}
*
- * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code KeyGeneratorSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("KeyGenerator",
KeyGeneratorSpi.class, algorithm, provider);
return new KeyGenerator((KeyGeneratorSpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/Mac.java
--- a/jdk/src/java.base/share/classes/javax/crypto/Mac.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/Mac.java Fri Nov 11 16:44:36 2016 +0100
@@ -166,16 +166,18 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new {@code Mac} object.
+ * @return the new {@code Mac} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * MacSpi implementation for the
- * specified algorithm.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code MacSpi} implementation for the specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
List services = GetInstance.getServices("Mac", algorithm);
// make sure there is at least one service from a signed provider
Iterator t = services.iterator();
@@ -210,22 +212,25 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code Mac} object.
+ * @return the new {@code Mac} object
*
- * @exception NoSuchAlgorithmException if a MacSpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if a {@code MacSpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null or empty.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("Mac", MacSpi.class, algorithm, provider);
return new Mac((MacSpi)instance.impl, instance.provider, algorithm);
@@ -248,19 +253,22 @@
*
* @param provider the provider.
*
- * @return the new {@code Mac} object.
+ * @return the new {@code Mac} object
+ *
+ * @throws IllegalArgumentException if the {@code provider} is
+ * {@code null}
*
- * @exception NoSuchAlgorithmException if a MacSpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code MacSpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("Mac", MacSpi.class, algorithm, provider);
return new Mac((MacSpi)instance.impl, instance.provider, algorithm);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/crypto/SecretKeyFactory.java
--- a/jdk/src/java.base/share/classes/javax/crypto/SecretKeyFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/crypto/SecretKeyFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -152,19 +152,19 @@
* Java Cryptography Architecture Standard Algorithm Name Documentation
* for information about standard algorithm names.
*
- * @return the new {@code SecretKeyFactory} object.
+ * @return the new {@code SecretKeyFactory} object
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code SecretKeyFactorySpi} implementation for the
+ * specified algorithm
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * SecretKeyFactorySpi implementation for the
- * specified algorithm.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
return new SecretKeyFactory(algorithm);
}
@@ -189,26 +189,26 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code SecretKeyFactory} object.
+ * @return the new {@code SecretKeyFactory} object
*
- * @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null} or empty
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws NoSuchAlgorithmException if a {@code SecretKeyFactorySpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null or empty.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("SecretKeyFactory",
SecretKeyFactorySpi.class, algorithm, provider);
return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
@@ -233,22 +233,22 @@
*
* @param provider the provider.
*
- * @return the new {@code SecretKeyFactory} object.
+ * @return the new {@code SecretKeyFactory} object
*
- * @exception NullPointerException if the specified algorithm
- * is null.
+ * @throws IllegalArgumentException if the {@code provider}
+ * is {@code null}
*
- * @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code SecretKeyFactorySpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @exception IllegalArgumentException if the {@code provider}
- * is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("SecretKeyFactory",
SecretKeyFactorySpi.class, algorithm, provider);
return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java
--- a/jdk/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -27,6 +27,7 @@
import java.security.Security;
import java.security.*;
+import java.util.Objects;
import sun.security.jca.GetInstance;
@@ -130,17 +131,19 @@
* Java Secure Socket Extension Reference Guide
* for information about standard algorithm names.
*
- * @return the new KeyManagerFactory
object.
+ * @return the new {@code KeyManagerFactory} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * KeyManagerFactorySpi implementation for the
- * specified algorithm.
- * @exception NullPointerException if algorithm
is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code KeyManagerFactorySpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm);
@@ -168,23 +171,26 @@
*
* @param provider the name of the provider.
*
- * @return the new KeyManagerFactory
object.
+ * @return the new {@code KeyManagerFactory} object
*
- * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is {@code null}
+ * or empty
+ *
+ * @throws NoSuchAlgorithmException if a {@code KeyManagerFactorySpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @throws IllegalArgumentException if the provider name is null or empty.
- * @throws NullPointerException if algorithm
is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm, provider);
@@ -209,19 +215,21 @@
*
* @param provider an instance of the provider.
*
- * @return the new KeyManagerFactory
object.
+ * @return the new {@code KeyManagerFactory} object
+ *
+ * @throws IllegalArgumentException if provider is {@code null}
*
- * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code @KeyManagerFactorySpi}
+ * implementation for the specified algorithm is not available
+ * from the specified Provider object
*
- * @throws IllegalArgumentException if provider is null.
- * @throws NullPointerException if algorithm
is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm, provider);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLContext.java Fri Nov 11 16:44:36 2016 +0100
@@ -26,6 +26,7 @@
package javax.net.ssl;
import java.security.*;
+import java.util.Objects;
import sun.security.jca.GetInstance;
@@ -151,17 +152,19 @@
* Documentation
* for information about standard protocol names.
*
- * @return the new {@code SSLContext} object.
+ * @return the new {@code SSLContext} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * SSLContextSpi implementation for the
- * specified protocol.
- * @exception NullPointerException if protocol is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code SSLContextSpi} implementation for the
+ * specified protocol
+ *
+ * @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
@@ -189,22 +192,25 @@
*
* @param provider the name of the provider.
*
- * @return the new {@code SSLContext} object.
+ * @return the new {@code SSLContext} object
*
- * @throws NoSuchAlgorithmException if a SSLContextSpi
- * implementation for the specified protocol is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is
+ * {@code null} or empty
+ *
+ * @throws NoSuchAlgorithmException if a {@code SSLContextSpi}
+ * implementation for the specified protocol is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @throws IllegalArgumentException if the provider name is null or empty.
- * @throws NullPointerException if protocol is null.
+ * @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
+ Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol, provider);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
@@ -229,19 +235,21 @@
*
* @param provider an instance of the provider.
*
- * @return the new {@code SSLContext} object.
+ * @return the new {@code SSLContext} object
+ *
+ * @throws IllegalArgumentException if the provider is {@code null}
*
- * @throws NoSuchAlgorithmException if a SSLContextSpi
- * implementation for the specified protocol is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code SSLContextSpi}
+ * implementation for the specified protocol is not available
+ * from the specified {@code Provider} object
*
- * @throws IllegalArgumentException if the provider is null.
- * @throws NullPointerException if protocol is null.
+ * @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol, Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol, provider);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java
--- a/jdk/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -27,6 +27,7 @@
import java.security.Security;
import java.security.*;
+import java.util.Objects;
import sun.security.jca.GetInstance;
@@ -144,17 +145,19 @@
* Java Secure Socket Extension Reference Guide
* for information about standard algorithm names.
*
- * @return the new TrustManagerFactory
object.
+ * @return the new {@code TrustManagerFactory} object
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * TrustManagerFactorySpi implementation for the
- * specified algorithm.
- * @exception NullPointerException if algorithm is null.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code TrustManagerFactorySpi} implementation for the
+ * specified algorithm
+ *
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm);
@@ -182,23 +185,26 @@
*
* @param provider the name of the provider.
*
- * @return the new TrustManagerFactory
object
+ * @return the new {@code TrustManagerFactory} object
*
- * @throws NoSuchAlgorithmException if a TrustManagerFactorySpi
- * implementation for the specified algorithm is not
- * available from the specified provider.
+ * @throws IllegalArgumentException if the provider name is
+ * {@code null} or empty
+ *
+ * @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
+ * implementation for the specified algorithm is not
+ * available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * registered in the security provider list
*
- * @throws IllegalArgumentException if the provider name is null or empty.
- * @throws NullPointerException if algorithm is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm, provider);
@@ -223,19 +229,21 @@
*
* @param provider an instance of the provider.
*
- * @return the new TrustManagerFactory
object.
+ * @return the new {@code TrustManagerFactory} object
+ *
+ * @throws IllegalArgumentException if the provider is {@code null}
*
- * @throws NoSuchAlgorithmException if a TrustManagerFactorySpi
- * implementation for the specified algorithm is not available
- * from the specified Provider object.
+ * @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
+ * implementation for the specified algorithm is not available
+ * from the specified {@code Provider} object
*
- * @throws IllegalArgumentException if the provider is null.
- * @throws NullPointerException if algorithm is null.
+ * @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
+ Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm, provider);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java
--- a/jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/javax/security/auth/login/Configuration.java Fri Nov 11 16:44:36 2016 +0100
@@ -329,27 +329,29 @@
*
* @param params parameters for the Configuration, which may be null.
*
- * @return the new Configuration object.
+ * @return the new {@code Configuration} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Configuration instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified parameters
+ * are not understood by the {@code ConfigurationSpi}
+ * implementation from the selected {@code Provider}
*
- * @exception IllegalArgumentException if the specified parameters
- * are not understood by the ConfigurationSpi implementation
- * from the selected Provider.
+ * @throws NoSuchAlgorithmException if no {@code Provider} supports a
+ * {@code ConfigurationSpi} implementation for the specified type
*
- * @exception NoSuchAlgorithmException if no Provider supports a
- * ConfigurationSpi implementation for the specified type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Configuration} instance for the specified type
*
* @see Provider
+ *
* @since 1.6
*/
public static Configuration getInstance(String type,
Configuration.Parameters params)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
checkPermission(type);
try {
GetInstance.Instance instance = GetInstance.getInstance
@@ -387,24 +389,24 @@
*
* @param provider the provider.
*
- * @return the new Configuration object.
+ * @return the new {@code Configuration} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Configuration instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified provider
+ * is {@code null} or empty, or if the specified parameters
+ * are not understood by the {@code ConfigurationSpi}
+ * implementation from the specified provider
*
- * @exception IllegalArgumentException if the specified provider
- * is null or empty,
- * or if the specified parameters are not understood by
- * the ConfigurationSpi implementation from the specified provider.
+ * @throws NoSuchProviderException if the specified provider is not
+ * registered in the security provider list
*
- * @exception NoSuchProviderException if the specified provider is not
- * registered in the security provider list.
+ * @throws NoSuchAlgorithmException if the specified provider does not
+ * support a {@code ConfigurationSpi} implementation for the
+ * specified type
*
- * @exception NoSuchAlgorithmException if the specified provider does not
- * support a ConfigurationSpi implementation for the specified
- * type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Configuration} instance for the specified type
*
* @see Provider
* @since 1.6
@@ -414,6 +416,7 @@
String provider)
throws NoSuchProviderException, NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
if (provider == null || provider.length() == 0) {
throw new IllegalArgumentException("missing provider");
}
@@ -453,20 +456,21 @@
*
* @param provider the Provider.
*
- * @return the new Configuration object.
+ * @return the new {@code Configuration} object
*
- * @exception SecurityException if the caller does not have permission
- * to get a Configuration instance for the specified type.
- *
- * @exception NullPointerException if the specified type is null.
+ * @throws IllegalArgumentException if the specified {@code Provider}
+ * is {@code null}, or if the specified parameters are not
+ * understood by the {@code ConfigurationSpi} implementation
+ * from the specified Provider
*
- * @exception IllegalArgumentException if the specified Provider is null,
- * or if the specified parameters are not understood by
- * the ConfigurationSpi implementation from the specified Provider.
+ * @throws NoSuchAlgorithmException if the specified {@code Provider}
+ * does not support a {@code ConfigurationSpi} implementation
+ * for the specified type
*
- * @exception NoSuchAlgorithmException if the specified Provider does not
- * support a ConfigurationSpi implementation for the specified
- * type.
+ * @throws NullPointerException if {@code type} is {@code null}
+ *
+ * @throws SecurityException if the caller does not have permission
+ * to get a {@code Configuration} instance for the specified type
*
* @see Provider
* @since 1.6
@@ -476,6 +480,7 @@
Provider provider)
throws NoSuchAlgorithmException {
+ Objects.requireNonNull(type, "null type name");
if (provider == null) {
throw new IllegalArgumentException("missing provider");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Fri Nov 11 16:44:36 2016 +0100
@@ -176,6 +176,16 @@
}
/**
+ * Returns the {@code Entry} for a resource in a JMOD file section
+ * or {@code null} if not found.
+ */
+ public Entry getEntry(Section section, String name) {
+ String entry = section.jmodDir() + "/" + name;
+ ZipEntry ze = zipfile.getEntry(entry);
+ return (ze != null) ? new Entry(ze) : null;
+ }
+
+ /**
* Opens an {@code InputStream} for reading the named entry of the given
* section in this jmod file.
*
@@ -185,7 +195,6 @@
public InputStream getInputStream(Section section, String name)
throws IOException
{
-
String entry = section.jmodDir() + "/" + name;
ZipEntry e = zipfile.getEntry(entry);
if (e == null) {
@@ -195,6 +204,15 @@
}
/**
+ * Opens an {@code InputStream} for reading an entry in the JMOD file.
+ *
+ * @throws IOException if an I/O error occurs
+ */
+ public InputStream getInputStream(Entry entry) throws IOException {
+ return zipfile.getInputStream(entry.zipEntry());
+ }
+
+ /**
* Returns a stream of non-directory entries in this jmod file.
*/
public Stream stream() {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Fri Nov 11 16:44:36 2016 +0100
@@ -53,6 +53,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
+import java.util.stream.Stream;
import jdk.internal.module.ModulePatcher.PatchedModuleReader;
import jdk.internal.misc.VM;
@@ -144,9 +145,9 @@
/**
* Create a new instance.
*/
- BuiltinClassLoader(BuiltinClassLoader parent, URLClassPath ucp) {
+ BuiltinClassLoader(String name, BuiltinClassLoader parent, URLClassPath ucp) {
// ensure getParent() returns null when the parent is the boot loader
- super(parent == null || parent == ClassLoaders.bootLoader() ? null : parent);
+ super(name, parent == null || parent == ClassLoaders.bootLoader() ? null : parent);
this.parent = parent;
this.ucp = ucp;
@@ -749,6 +750,10 @@
return Optional.empty();
}
@Override
+ public Stream list() {
+ return Stream.empty();
+ }
+ @Override
public void close() {
throw new InternalError("Should not get here");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java Fri Nov 11 16:44:36 2016 +0100
@@ -69,16 +69,17 @@
bcp = toURLClassPath(s);
// we have a class path if -cp is specified or -m is not specified.
- // If neither is specified then default to -cp .
+ // If neither is specified then default to -cp
+ // If -cp is not specified and -m is specified, the value of
+ // java.class.path is an empty string, then no class path.
URLClassPath ucp = null;
String mainMid = System.getProperty("jdk.module.main");
String cp = System.getProperty("java.class.path");
- if (mainMid == null && cp == null)
+ if (cp == null)
cp = "";
- if (cp != null)
+ if (mainMid == null || cp.length() > 0)
ucp = toURLClassPath(cp);
-
// create the class loaders
BOOT_LOADER = new BootClassLoader(bcp);
PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
@@ -117,7 +118,7 @@
*/
private static class BootClassLoader extends BuiltinClassLoader {
BootClassLoader(URLClassPath bcp) {
- super(null, bcp);
+ super(null, null, bcp);
}
@Override
@@ -137,7 +138,7 @@
}
PlatformClassLoader(BootClassLoader parent) {
- super(parent, null);
+ super("platform", parent, null);
}
/**
@@ -164,7 +165,7 @@
final URLClassPath ucp;
AppClassLoader(PlatformClassLoader parent, URLClassPath ucp) {
- super(parent, ucp);
+ super("app", parent, ucp);
this.ucp = ucp;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/Loader.java Fri Nov 11 16:44:36 2016 +0100
@@ -53,6 +53,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
/**
@@ -534,6 +535,10 @@
return Optional.empty();
}
@Override
+ public Stream list() {
+ return Stream.empty();
+ }
+ @Override
public void close() {
throw new InternalError("Should not get here");
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -137,13 +137,20 @@
}
public static boolean isSystem(Module m) {
- ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() {
+ return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
- public ClassLoader run() {
- return m.getClassLoader();
+ public Boolean run() {
+ final ClassLoader moduleCL = m.getClassLoader();
+ if (moduleCL == null) return true;
+ ClassLoader cl = ClassLoader.getPlatformClassLoader();
+ while (cl != null && moduleCL != cl) {
+ cl = cl.getParent();
+ }
+ // returns true if moduleCL is the platform class loader
+ // or one of its ancestors.
+ return moduleCL == cl;
}
});
- return cl == null;
}
@Override
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Fri Nov 11 16:44:36 2016 +0100
@@ -39,6 +39,7 @@
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.net.URI;
+import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -103,6 +104,11 @@
ModuleHashes hashes);
/**
+ * Returns the object with the hashes of other modules
+ */
+ Optional hashes(ModuleDescriptor descriptor);
+
+ /**
* Resolves a collection of root modules, with service binding
* and the empty configuration as the parent. The post resolution
* checks are optionally run.
@@ -120,8 +126,10 @@
Supplier readerSupplier);
/**
- * Returns the object with the hashes of other modules
+ * Creates a ModuleFinder for a module path.
*/
- Optional hashes(ModuleDescriptor descriptor);
+ ModuleFinder newModulePath(Runtime.Version version,
+ boolean isLinkPhase,
+ Path... entries);
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/module/ConfigurableModuleFinder.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ConfigurableModuleFinder.java Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.module;
-
-import java.lang.module.ModuleFinder;
-
-/**
- * A ModuleFinder that may be configured to work at either run-time
- * or link-time.
- */
-
-public interface ConfigurableModuleFinder extends ModuleFinder {
-
- public static enum Phase {
- RUN_TIME,
- LINK_TIME
- }
-
- /**
- * Configures this finder to work in the given phase.
- */
- void configurePhase(Phase phase);
-
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoWriter.java Fri Nov 11 16:44:36 2016 +0100
@@ -57,7 +57,15 @@
cw.visit(Opcodes.V1_9, ACC_MODULE, name, null, null, null);
cw.visitAttribute(new ModuleAttribute(md));
- cw.visitAttribute(new ConcealedPackagesAttribute(md.conceals()));
+
+ // for tests: write the ConcealedPackages attribute when there are non-exported packages
+ long nExportedPackages = md.exports().stream()
+ .map(ModuleDescriptor.Exports::source)
+ .distinct()
+ .count();
+ if (md.packages().size() > nExportedPackages)
+ cw.visitAttribute(new ConcealedPackagesAttribute(md.packages()));
+
md.version().ifPresent(v -> cw.visitAttribute(new VersionAttribute(v)));
md.mainClass().ifPresent(mc -> cw.visitAttribute(new MainClassAttribute(mc)));
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Fri Nov 11 16:44:36 2016 +0100
@@ -50,6 +50,7 @@
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import java.util.stream.Stream;
import jdk.internal.loader.Resource;
import jdk.internal.misc.JavaLangModuleAccess;
@@ -159,21 +160,19 @@
// is not supported by the boot class loader
try (JarFile jf = new JarFile(file.toFile())) {
jf.stream()
- .filter(e -> e.getName().endsWith(".class"))
.map(e -> toPackageName(file, e))
- .filter(pn -> pn.length() > 0)
+ .filter(Checks::isJavaIdentifier)
.forEach(packages::add);
}
} else if (Files.isDirectory(file)) {
- // exploded directory
+ // exploded directory without following sym links
Path top = file;
Files.find(top, Integer.MAX_VALUE,
- ((path, attrs) -> attrs.isRegularFile() &&
- path.toString().endsWith(".class")))
+ ((path, attrs) -> attrs.isRegularFile()))
.map(path -> toPackageName(top, path))
- .filter(pn -> pn.length() > 0)
+ .filter(Checks::isJavaIdentifier)
.forEach(packages::add);
}
@@ -381,6 +380,15 @@
}
@Override
+ public Stream list() throws IOException {
+ Stream s = delegate().list();
+ for (ResourceFinder finder : finders) {
+ s = Stream.concat(s, finder.list());
+ }
+ return s.distinct();
+ }
+
+ @Override
public void close() throws IOException {
closeAll(finders);
delegate().close();
@@ -393,6 +401,7 @@
*/
private static interface ResourceFinder extends Closeable {
Resource find(String name) throws IOException;
+ Stream list() throws IOException;
}
@@ -453,6 +462,13 @@
}
};
}
+
+ @Override
+ public Stream list() throws IOException {
+ return jf.stream()
+ .filter(e -> !e.isDirectory())
+ .map(JarEntry::getName);
+ }
}
@@ -527,6 +543,15 @@
}
};
}
+
+ @Override
+ public Stream list() throws IOException {
+ return Files.find(dir, Integer.MAX_VALUE,
+ (path, attrs) -> attrs.isRegularFile())
+ .map(f -> dir.relativize(f)
+ .toString()
+ .replace(File.separatorChar, '/'));
+ }
}
@@ -537,7 +562,7 @@
Path entry = top.relativize(file);
Path parent = entry.getParent();
if (parent == null) {
- return warnUnnamedPackage(top, entry.toString());
+ return warnIfModuleInfo(top, entry.toString());
} else {
return parent.toString().replace(File.separatorChar, '.');
}
@@ -557,14 +582,15 @@
String name = entry.getName();
int index = name.lastIndexOf("/");
if (index == -1) {
- return warnUnnamedPackage(file, name);
+ return warnIfModuleInfo(file, name);
} else {
return name.substring(0, index).replace('/', '.');
}
}
- private static String warnUnnamedPackage(Path file, String e) {
- System.err.println("WARNING: " + e + " not allowed in patch: " + file);
+ private static String warnIfModuleInfo(Path file, String e) {
+ if (e.equals("module-info.class"))
+ System.err.println("WARNING: " + e + " ignored in patch: " + file);
return "";
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Fri Nov 11 16:44:36 2016 +0100
@@ -364,6 +364,16 @@
}
}
+ public final Constructor> newConstructorForSerialization(Class> cl,
+ Constructor> constructorToCall)
+ {
+ if (constructorToCall.getDeclaringClass() == cl) {
+ constructorToCall.setAccessible(true);
+ return constructorToCall;
+ }
+ return generateConstructor(cl, constructorToCall);
+ }
+
public final Constructor> newConstructorForSerialization(Class> cl) {
Class> initCl = cl;
while (Serializable.class.isAssignableFrom(initCl)) {
@@ -383,6 +393,12 @@
} catch (NoSuchMethodException ex) {
return null;
}
+ return generateConstructor(cl, constructorToCall);
+ }
+
+ private final Constructor> generateConstructor(Class> cl,
+ Constructor> constructorToCall) {
+
ConstructorAccessor acc = new MethodAccessorGenerator().
generateSerializationConstructor(cl,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/module-info.java
--- a/jdk/src/java.base/share/classes/module-info.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/module-info.java Fri Nov 11 16:44:36 2016 +0100
@@ -196,7 +196,8 @@
jdk.vm.ci;
exports jdk.internal.util.jar to
jdk.jartool,
- jdk.jdeps;
+ jdk.jdeps,
+ jdk.jlink;
exports jdk.internal.vm to
java.management,
jdk.jvmstat;
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
\ (to execute the main class in a module)\n\
where options include:\n
-java.launcher.opt.datamodel =\ -d{0}\t use a {0}-bit data model if available\n
+java.launcher.opt.datamodel =\ -d{0}\t Deprecated, will be removed in a future release\n
java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
java.launcher.opt.hotspot =\ {0}\t is a synonym for the "{1}" VM [deprecated]\n
@@ -95,6 +95,12 @@
\ load Java programming language agent, see java.lang.instrument\n\
\ -splash:\n\
\ show splash screen with specified image\n\
+\ HiDPI scaled images are automatically supported and used\n\
+\ if available. The unscaled image filename, e.g. image.ext,\n\
+\ should always be passed as the argument to the -splash option.\n\
+\ The most appropriate scaled image provided will be picked up\n\
+\ automatically.\n\
+\ See the SplashScreen API documentation for more information.\n\
\ @ read options from the specified file\n\
\To specify an argument for a long option, you can use --= or\n\
\-- .\n\
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 11 16:44:36 2016 +0100
@@ -253,20 +253,20 @@
}
private static String toSourceString(char c) {
- StringBuilder sb = new StringBuilder();
- sb.append("'");
+ StringBuilder sb = new StringBuilder(4);
+ sb.append('\'');
if (c == '\'')
sb.append("\\'");
else
sb.append(c);
- sb.append("'");
- return sb.toString();
+ return sb.append('\'')
+ .toString();
}
private static String toSourceString(long ell) {
- return (Math.abs(ell) <= Integer.MAX_VALUE) ?
- String.valueOf(ell) :
- (String.valueOf(ell) + "L");
+ String str = String.valueOf(ell);
+ return (ell < Integer.MIN_VALUE || ell > Integer.MAX_VALUE)
+ ? (str + 'L') : str;
}
/**
@@ -278,10 +278,7 @@
sb.append('"');
// Escape embedded quote characters, if present, but don't do
// anything more heroic.
- if (s.indexOf('"') != -1) {
- s = s.replace("\"", "\\\"");
- }
- sb.append(s);
+ sb.append(s.replace("\"", "\\\""));
sb.append('"');
return sb.toString();
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DTLSInputRecord.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,10 +42,6 @@
private DTLSReassembler reassembler = null;
- // Cache the session identifier for the detection of session-resuming
- // handshake.
- byte[] prevSessionID = new byte[0];
-
int readEpoch;
int prevReadEpoch;
@@ -114,13 +110,7 @@
@Override
Plaintext acquirePlaintext() {
if (reassembler != null) {
- Plaintext plaintext = reassembler.acquirePlaintext();
- if (reassembler.finished()) {
- // discard all buffered unused message.
- reassembler = null;
- }
-
- return plaintext;
+ return reassembler.acquirePlaintext();
}
return null;
@@ -149,40 +139,54 @@
packet.get(recordEnS);
int recordEpoch = ((recordEnS[0] & 0xFF) << 8) |
(recordEnS[1] & 0xFF); // pos: 3, 4
- long recordSeq = Authenticator.toLong(recordEnS);
+ long recordSeq = ((recordEnS[2] & 0xFFL) << 40) |
+ ((recordEnS[3] & 0xFFL) << 32) |
+ ((recordEnS[4] & 0xFFL) << 24) |
+ ((recordEnS[5] & 0xFFL) << 16) |
+ ((recordEnS[6] & 0xFFL) << 8) |
+ (recordEnS[7] & 0xFFL); // pos: 5-10
+
int contentLen = ((packet.get() & 0xFF) << 8) |
- (packet.get() & 0xFF); // pos: 11, 12
+ (packet.get() & 0xFF); // pos: 11, 12
if (debug != null && Debug.isOn("record")) {
- System.out.println(Thread.currentThread().getName() +
- ", READ: " +
+ Debug.log("READ: " +
ProtocolVersion.valueOf(majorVersion, minorVersion) +
" " + Record.contentName(contentType) + ", length = " +
contentLen);
}
int recLim = srcPos + DTLSRecord.headerSize + contentLen;
- if (this.readEpoch > recordEpoch) {
- // Discard old records delivered before this epoch.
+ if (this.prevReadEpoch > recordEpoch) {
// Reset the position of the packet buffer.
packet.position(recLim);
+ if (debug != null && Debug.isOn("record")) {
+ Debug.printHex("READ: discard this old record", recordEnS);
+ }
return null;
}
+ // Buffer next epoch message if necessary.
if (this.readEpoch < recordEpoch) {
- if (contentType != Record.ct_handshake) {
- // just discard it if not a handshake message
+ // Discard the record younger than the current epcoh if:
+ // 1. it is not a handshake message, or
+ // 2. it is not of next epoch.
+ if (((contentType != Record.ct_handshake) &&
+ (contentType != Record.ct_change_cipher_spec)) ||
+ (this.readEpoch < (recordEpoch - 1))) {
+
packet.position(recLim);
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Premature record (epoch), discard it.");
+ }
+
return null;
}
- // Not ready to decrypt this record, may be encrypted Finished
+ // Not ready to decrypt this record, may be an encrypted Finished
// message, need to buffer it.
- if (reassembler == null) {
- reassembler = new DTLSReassembler();
- }
-
byte[] fragment = new byte[contentLen];
packet.get(fragment); // copy the fragment
RecordFragment buffered = new RecordFragment(fragment, contentType,
@@ -194,94 +198,130 @@
// consume the full record in the packet buffer.
packet.position(recLim);
- Plaintext plaintext = reassembler.acquirePlaintext();
- if (reassembler.finished()) {
- // discard all buffered unused message.
+ return reassembler.acquirePlaintext();
+ }
+
+ //
+ // Now, the message is of this epoch or the previous epoch.
+ //
+ Authenticator decodeAuthenticator;
+ CipherBox decodeCipher;
+ if (this.readEpoch == recordEpoch) {
+ decodeAuthenticator = readAuthenticator;
+ decodeCipher = readCipher;
+ } else { // prevReadEpoch == recordEpoch
+ decodeAuthenticator = prevReadAuthenticator;
+ decodeCipher = prevReadCipher;
+ }
+
+ // decrypt the fragment
+ packet.limit(recLim);
+ packet.position(srcPos + DTLSRecord.headerSize);
+
+ ByteBuffer plaintextFragment;
+ try {
+ plaintextFragment = decrypt(decodeAuthenticator,
+ decodeCipher, contentType, packet, recordEnS);
+ } catch (BadPaddingException bpe) {
+ if (debug != null && Debug.isOn("ssl")) {
+ Debug.log("Discard invalid record: " + bpe);
+ }
+
+ // invalid, discard this record [section 4.1.2.7, RFC 6347]
+ return null;
+ } finally {
+ // comsume a complete record
+ packet.limit(srcLim);
+ packet.position(recLim);
+ }
+
+ if (contentType != Record.ct_change_cipher_spec &&
+ contentType != Record.ct_handshake) { // app data or alert
+ // no retransmission
+ // Cleanup the handshake reassembler if necessary.
+ if ((reassembler != null) &&
+ (reassembler.handshakeEpoch < recordEpoch)) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Cleanup the handshake reassembler");
+ }
+
reassembler = null;
}
- return plaintext;
+ return new Plaintext(contentType, majorVersion, minorVersion,
+ recordEpoch, Authenticator.toLong(recordEnS),
+ plaintextFragment);
}
- if (this.readEpoch == recordEpoch) {
- // decrypt the fragment
- packet.limit(recLim);
- packet.position(srcPos + DTLSRecord.headerSize);
-
- ByteBuffer plaintextFragment;
- try {
- plaintextFragment = decrypt(readAuthenticator,
- readCipher, contentType, packet, recordEnS);
- } catch (BadPaddingException bpe) {
- if (debug != null && Debug.isOn("ssl")) {
- System.out.println(Thread.currentThread().getName() +
- " discard invalid record: " + bpe);
- }
-
- // invalid, discard this record [section 4.1.2.7, RFC 6347]
- return null;
- } finally {
- // comsume a complete record
- packet.limit(srcLim);
- packet.position(recLim);
- }
-
- if (contentType != Record.ct_change_cipher_spec &&
- contentType != Record.ct_handshake) { // app data or alert
- // no retransmission
- return new Plaintext(contentType, majorVersion, minorVersion,
- recordEpoch, recordSeq, plaintextFragment);
- }
-
- if (contentType == Record.ct_change_cipher_spec) {
- if (reassembler == null) {
+ if (contentType == Record.ct_change_cipher_spec) {
+ if (reassembler == null) {
+ if (this.readEpoch != recordEpoch) {
// handshake has not started, should be an
// old handshake message, discard it.
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Lagging behind ChangeCipherSpec, discard it.");
+ }
+
return null;
}
- reassembler.queueUpFragment(
- new RecordFragment(plaintextFragment, contentType,
- majorVersion, minorVersion,
- recordEnS, recordEpoch, recordSeq, false));
- } else { // handshake record
- // One record may contain 1+ more handshake messages.
- while (plaintextFragment.remaining() > 0) {
+ reassembler = new DTLSReassembler(recordEpoch);
+ }
+
+ reassembler.queueUpChangeCipherSpec(
+ new RecordFragment(plaintextFragment, contentType,
+ majorVersion, minorVersion,
+ recordEnS, recordEpoch, recordSeq, false));
+ } else { // handshake record
+ // One record may contain 1+ more handshake messages.
+ while (plaintextFragment.remaining() > 0) {
+
+ HandshakeFragment hsFrag = parseHandshakeMessage(
+ contentType, majorVersion, minorVersion,
+ recordEnS, recordEpoch, recordSeq, plaintextFragment);
- HandshakeFragment hsFrag = parseHandshakeMessage(
- contentType, majorVersion, minorVersion,
- recordEnS, recordEpoch, recordSeq, plaintextFragment);
+ if (hsFrag == null) {
+ // invalid, discard this record
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Invalid handshake message, discard it.");
+ }
+
+ return null;
+ }
- if (hsFrag == null) {
- // invalid, discard this record
+ if (reassembler == null) {
+ if (this.readEpoch != recordEpoch) {
+ // handshake has not started, should be an
+ // old handshake message, discard it.
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Lagging behind handshake record, discard it.");
+ }
+
return null;
}
- if ((reassembler == null) &&
- isKickstart(hsFrag.handshakeType)) {
- reassembler = new DTLSReassembler();
- }
-
- if (reassembler != null) {
- reassembler.queueUpHandshake(hsFrag);
- } // else, just ignore the message.
- }
- }
-
- // Completed the read of the full record. Acquire the reassembled
- // messages.
- if (reassembler != null) {
- Plaintext plaintext = reassembler.acquirePlaintext();
- if (reassembler.finished()) {
- // discard all buffered unused message.
- reassembler = null;
+ reassembler = new DTLSReassembler(recordEpoch);
}
- return plaintext;
+ reassembler.queueUpHandshake(hsFrag);
}
}
- return null; // make the complier happy
+ // Completed the read of the full record. Acquire the reassembled
+ // messages.
+ if (reassembler != null) {
+ return reassembler.acquirePlaintext();
+ }
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("The reassembler is not initialized yet.");
+ }
+
+ return null;
}
@Override
@@ -330,12 +370,6 @@
}
}
- private static boolean isKickstart(byte handshakeType) {
- return (handshakeType == HandshakeMessage.ht_client_hello) ||
- (handshakeType == HandshakeMessage.ht_hello_request) ||
- (handshakeType == HandshakeMessage.ht_hello_verify_request);
- }
-
private static HandshakeFragment parseHandshakeMessage(
byte contentType, byte majorVersion, byte minorVersion,
byte[] recordEnS, int recordEpoch, long recordSeq,
@@ -344,9 +378,7 @@
int remaining = plaintextFragment.remaining();
if (remaining < handshakeHeaderSize) {
if (debug != null && Debug.isOn("ssl")) {
- System.out.println(
- Thread.currentThread().getName() +
- " discard invalid record: " +
+ Debug.log("Discard invalid record: " +
"too small record to hold a handshake fragment");
}
@@ -372,9 +404,7 @@
(plaintextFragment.get() & 0xFF); // pos: 9-11
if ((remaining - handshakeHeaderSize) < fragmentLength) {
if (debug != null && Debug.isOn("ssl")) {
- System.out.println(
- Thread.currentThread().getName() +
- " discard invalid record: " +
+ Debug.log("Discard invalid record: " +
"not a complete handshake fragment in the record");
}
@@ -431,7 +461,39 @@
@Override
public int compareTo(RecordFragment o) {
- return Long.compareUnsigned(this.recordSeq, o.recordSeq);
+ if (this.contentType == Record.ct_change_cipher_spec) {
+ if (o.contentType == Record.ct_change_cipher_spec) {
+ // Only one incoming ChangeCipherSpec message for an epoch.
+ //
+ // Ignore duplicated ChangeCipherSpec messages.
+ return Integer.compare(this.recordEpoch, o.recordEpoch);
+ } else if ((this.recordEpoch == o.recordEpoch) &&
+ (o.contentType == Record.ct_handshake)) {
+ // ChangeCipherSpec is the latest message of an epoch.
+ return 1;
+ }
+ } else if (o.contentType == Record.ct_change_cipher_spec) {
+ if ((this.recordEpoch == o.recordEpoch) &&
+ (this.contentType == Record.ct_handshake)) {
+ // ChangeCipherSpec is the latest message of an epoch.
+ return -1;
+ } else {
+ // different epoch or this is not a handshake message
+ return compareToSequence(o.recordEpoch, o.recordSeq);
+ }
+ }
+
+ return compareToSequence(o.recordEpoch, o.recordSeq);
+ }
+
+ int compareToSequence(int epoch, long seq) {
+ if (this.recordEpoch > epoch) {
+ return 1;
+ } else if (this.recordEpoch == epoch) {
+ return Long.compare(this.recordSeq, seq);
+ } else {
+ return -1;
+ }
}
}
@@ -465,12 +527,24 @@
if (o instanceof HandshakeFragment) {
HandshakeFragment other = (HandshakeFragment)o;
if (this.messageSeq != other.messageSeq) {
- // keep the insertion order for the same message
+ // keep the insertion order of handshake messages
return this.messageSeq - other.messageSeq;
+ } else if (this.fragmentOffset != other.fragmentOffset) {
+ // small fragment offset was transmitted first
+ return this.fragmentOffset - other.fragmentOffset;
+ } else if (this.fragmentLength == other.fragmentLength) {
+ // retransmissions, ignore duplicated messages.
+ return 0;
}
+
+ // Should be repacked for suitable fragment length.
+ //
+ // Note that the acquiring processes will reassemble the
+ // the fragments later.
+ return compareToSequence(o.recordEpoch, o.recordSeq);
}
- return Long.compareUnsigned(this.recordSeq, o.recordSeq);
+ return super.compareTo(o);
}
}
@@ -484,24 +558,72 @@
}
}
+ private static final class HandshakeFlight implements Cloneable {
+ static final byte HF_UNKNOWN = HandshakeMessage.ht_not_applicable;
+
+ byte handshakeType; // handshake type
+ int flightEpoch; // the epoch of the first message
+ int minMessageSeq; // minimal message sequence
+
+ int maxMessageSeq; // maximum message sequence
+ int maxRecordEpoch; // maximum record sequence number
+ long maxRecordSeq; // maximum record sequence number
+
+ HashMap> holesMap;
+
+ HandshakeFlight() {
+ this.handshakeType = HF_UNKNOWN;
+ this.flightEpoch = 0;
+ this.minMessageSeq = 0;
+
+ this.maxMessageSeq = 0;
+ this.maxRecordEpoch = 0;
+ this.maxRecordSeq = -1;
+
+ this.holesMap = new HashMap<>(5);
+ }
+
+ boolean isRetransmitOf(HandshakeFlight hs) {
+ return (hs != null) &&
+ (this.handshakeType == hs.handshakeType) &&
+ (this.minMessageSeq == hs.minMessageSeq);
+ }
+
+ @Override
+ public Object clone() {
+ HandshakeFlight hf = new HandshakeFlight();
+
+ hf.handshakeType = this.handshakeType;
+ hf.flightEpoch = this.flightEpoch;
+ hf.minMessageSeq = this.minMessageSeq;
+
+ hf.maxMessageSeq = this.maxMessageSeq;
+ hf.maxRecordEpoch = this.maxRecordEpoch;
+ hf.maxRecordSeq = this.maxRecordSeq;
+
+ hf.holesMap = new HashMap<>(this.holesMap);
+
+ return hf;
+ }
+ }
+
final class DTLSReassembler {
+ // The handshake epoch.
+ final int handshakeEpoch;
+
+ // The buffered fragments.
TreeSet bufferedFragments = new TreeSet<>();
- HashMap> holesMap = new HashMap<>(5);
+ // The handshake flight in progress.
+ HandshakeFlight handshakeFlight = new HandshakeFlight();
- // Epoch, sequence number and handshake message sequence of the
- // beginning message of a flight.
- byte flightType = (byte)0xFF;
-
- int flightTopEpoch = 0;
- long flightTopRecordSeq = -1;
- int flightTopMessageSeq = 0;
+ // The preceding handshake flight.
+ HandshakeFlight precedingFlight = null;
// Epoch, sequence number and handshake message sequence of the
// next message acquisition of a flight.
- int nextRecordEpoch = 0; // next record epoch
+ int nextRecordEpoch; // next record epoch
long nextRecordSeq = 0; // next record sequence number
- int nextMessageSeq = 0; // next handshake message number
// Expect ChangeCipherSpec and Finished messages for the final flight.
boolean expectCCSFlight = false;
@@ -510,65 +632,66 @@
boolean flightIsReady = false;
boolean needToCheckFlight = false;
- // Is it a session-resuming abbreviated handshake.?
- boolean isAbbreviatedHandshake = false;
-
- // The handshke fragment with the biggest record sequence number
- // in a flight, not counting the Finished message.
- HandshakeFragment lastHandshakeFragment = null;
+ DTLSReassembler(int handshakeEpoch) {
+ this.handshakeEpoch = handshakeEpoch;
+ this.nextRecordEpoch = handshakeEpoch;
- // Is handshake (intput) finished?
- boolean handshakeFinished = false;
-
- DTLSReassembler() {
- // blank
- }
-
- boolean finished() {
- return handshakeFinished;
+ this.handshakeFlight.flightEpoch = handshakeEpoch;
}
void expectingFinishFlight() {
expectCCSFlight = true;
}
+ // Queue up a handshake message.
void queueUpHandshake(HandshakeFragment hsf) {
-
- if ((nextRecordEpoch > hsf.recordEpoch) ||
- (nextRecordSeq > hsf.recordSeq) ||
- (nextMessageSeq > hsf.messageSeq)) {
- // too old, discard this record
+ if (!isDesirable(hsf)) {
+ // Not a dedired record, discard it.
return;
}
- // Is it the first message of next flight?
- if ((flightTopMessageSeq == hsf.messageSeq) &&
- (hsf.fragmentOffset == 0) && (flightTopRecordSeq == -1)) {
+ // Clean up the retransmission messages if necessary.
+ cleanUpRetransmit(hsf);
- flightType = hsf.handshakeType;
- flightTopEpoch = hsf.recordEpoch;
- flightTopRecordSeq = hsf.recordSeq;
+ // Is it the first message of next flight?
+ //
+ // Note: the Finished message is handled in the final CCS flight.
+ boolean isMinimalFlightMessage = false;
+ if (handshakeFlight.minMessageSeq == hsf.messageSeq) {
+ isMinimalFlightMessage = true;
+ } else if ((precedingFlight != null) &&
+ (precedingFlight.minMessageSeq == hsf.messageSeq)) {
+ isMinimalFlightMessage = true;
+ }
+
+ if (isMinimalFlightMessage && (hsf.fragmentOffset == 0) &&
+ (hsf.handshakeType != HandshakeMessage.ht_finished)) {
- if (hsf.handshakeType == HandshakeMessage.ht_server_hello) {
- // Is it a session-resuming handshake?
- try {
- isAbbreviatedHandshake =
- isSessionResuming(hsf.fragment, prevSessionID);
- } catch (SSLException ssle) {
- if (debug != null && Debug.isOn("ssl")) {
- System.out.println(
- Thread.currentThread().getName() +
- " discard invalid record: " + ssle);
- }
+ // reset the handshake flight
+ handshakeFlight.handshakeType = hsf.handshakeType;
+ handshakeFlight.flightEpoch = hsf.recordEpoch;
+ handshakeFlight.minMessageSeq = hsf.messageSeq;
+ }
- // invalid, discard it [section 4.1.2.7, RFC 6347]
- return;
- }
+ if (hsf.handshakeType == HandshakeMessage.ht_finished) {
+ handshakeFlight.maxMessageSeq = hsf.messageSeq;
+ handshakeFlight.maxRecordEpoch = hsf.recordEpoch;
+ handshakeFlight.maxRecordSeq = hsf.recordSeq;
+ } else {
+ if (handshakeFlight.maxMessageSeq < hsf.messageSeq) {
+ handshakeFlight.maxMessageSeq = hsf.messageSeq;
+ }
- if (!isAbbreviatedHandshake) {
- prevSessionID = getSessionID(hsf.fragment);
+ int n = (hsf.recordEpoch - handshakeFlight.maxRecordEpoch);
+ if (n > 0) {
+ handshakeFlight.maxRecordEpoch = hsf.recordEpoch;
+ handshakeFlight.maxRecordSeq = hsf.recordSeq;
+ } else if (n == 0) {
+ // the same epoch
+ if (handshakeFlight.maxRecordSeq < hsf.recordSeq) {
+ handshakeFlight.maxRecordSeq = hsf.recordSeq;
}
- }
+ } // Otherwise, it is unlikely to happen.
}
boolean fragmented = false;
@@ -578,7 +701,8 @@
fragmented = true;
}
- List holes = holesMap.get(hsf.handshakeType);
+ List holes =
+ handshakeFlight.holesMap.get(hsf.handshakeType);
if (holes == null) {
if (!fragmented) {
holes = Collections.emptyList();
@@ -586,7 +710,7 @@
holes = new LinkedList();
holes.add(new HoleDescriptor(0, hsf.messageLength));
}
- holesMap.put(hsf.handshakeType, holes);
+ handshakeFlight.holesMap.put(hsf.handshakeType, holes);
} else if (holes.isEmpty()) {
// Have got the full handshake message. This record may be
// a handshake message retransmission. Discard this record.
@@ -594,20 +718,11 @@
// It's OK to discard retransmission as the handshake hash
// is computed as if each handshake message had been sent
// as a single fragment.
- //
- // Note that ClientHello messages are delivered twice in
- // DTLS handshaking.
- if ((hsf.handshakeType != HandshakeMessage.ht_client_hello &&
- hsf.handshakeType != ht_hello_verify_request) ||
- (nextMessageSeq != hsf.messageSeq)) {
- return;
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Have got the full message, discard it.");
}
- if (fragmented) {
- holes = new LinkedList();
- holes.add(new HoleDescriptor(0, hsf.messageLength));
- }
- holesMap.put(hsf.handshakeType, holes);
+ return;
}
if (fragmented) {
@@ -628,9 +743,7 @@
(hole.limit < fragmentLimit))) {
if (debug != null && Debug.isOn("ssl")) {
- System.out.println(
- Thread.currentThread().getName() +
- " discard invalid record: " +
+ Debug.log("Discard invalid record: " +
"handshake fragment ranges are overlapping");
}
@@ -659,48 +772,205 @@
}
}
- // append this fragment
- bufferedFragments.add(hsf);
-
- if ((lastHandshakeFragment == null) ||
- (lastHandshakeFragment.compareTo(hsf) < 0)) {
-
- lastHandshakeFragment = hsf;
+ // buffer this fragment
+ if (hsf.handshakeType == HandshakeMessage.ht_finished) {
+ // Need no status update.
+ bufferedFragments.add(hsf);
+ } else {
+ bufferFragment(hsf);
}
-
- if (flightIsReady) {
- flightIsReady = false;
- }
- needToCheckFlight = true;
}
- // queue up change_cipher_spec or encrypted message
- void queueUpFragment(RecordFragment rf) {
- if ((nextRecordEpoch > rf.recordEpoch) ||
- (nextRecordSeq > rf.recordSeq)) {
- // too old, discard this record
+ // Queue up a ChangeCipherSpec message
+ void queueUpChangeCipherSpec(RecordFragment rf) {
+ if (!isDesirable(rf)) {
+ // Not a dedired record, discard it.
return;
}
- // Is it the first message of next flight?
- if (expectCCSFlight &&
- (rf.contentType == Record.ct_change_cipher_spec)) {
+ // Clean up the retransmission messages if necessary.
+ cleanUpRetransmit(rf);
- flightType = (byte)0xFE;
- flightTopEpoch = rf.recordEpoch;
- flightTopRecordSeq = rf.recordSeq;
+ // Is it the first message of this flight?
+ //
+ // Note: the first message of the final flight is ChangeCipherSpec.
+ if (expectCCSFlight) {
+ handshakeFlight.handshakeType = HandshakeFlight.HF_UNKNOWN;
+ handshakeFlight.flightEpoch = rf.recordEpoch;
+ }
+
+ // The epoch should be the same as the first message of the flight.
+ if (handshakeFlight.maxRecordSeq < rf.recordSeq) {
+ handshakeFlight.maxRecordSeq = rf.recordSeq;
}
+ // buffer this fragment
+ bufferFragment(rf);
+ }
+
+ // Queue up a ciphertext message.
+ //
+ // Note: not yet be able to decrypt the message.
+ void queueUpFragment(RecordFragment rf) {
+ if (!isDesirable(rf)) {
+ // Not a dedired record, discard it.
+ return;
+ }
+
+ // Clean up the retransmission messages if necessary.
+ cleanUpRetransmit(rf);
+
+ // buffer this fragment
+ bufferFragment(rf);
+ }
+
+ private void bufferFragment(RecordFragment rf) {
// append this fragment
bufferedFragments.add(rf);
if (flightIsReady) {
flightIsReady = false;
}
- needToCheckFlight = true;
+
+ if (!needToCheckFlight) {
+ needToCheckFlight = true;
+ }
+ }
+
+ private void cleanUpRetransmit(RecordFragment rf) {
+ // Does the next flight start?
+ boolean isNewFlight = false;
+ if (precedingFlight != null) {
+ if (precedingFlight.flightEpoch < rf.recordEpoch) {
+ isNewFlight = true;
+ } else {
+ if (rf instanceof HandshakeFragment) {
+ HandshakeFragment hsf = (HandshakeFragment)rf;
+ if (precedingFlight.maxMessageSeq < hsf.messageSeq) {
+ isNewFlight = true;
+ }
+ } else if (rf.contentType != Record.ct_change_cipher_spec) {
+ // ciphertext
+ if (precedingFlight.maxRecordEpoch < rf.recordEpoch) {
+ isNewFlight = true;
+ }
+ }
+ }
+ }
+
+ if (!isNewFlight) {
+ // Need no cleanup.
+ return;
+ }
+
+ // clean up the buffer
+ for (Iterator it = bufferedFragments.iterator();
+ it.hasNext();) {
+
+ RecordFragment frag = it.next();
+ boolean isOld = false;
+ if (frag.recordEpoch < precedingFlight.maxRecordEpoch) {
+ isOld = true;
+ } else if (frag.recordEpoch == precedingFlight.maxRecordEpoch) {
+ if (frag.recordSeq <= precedingFlight.maxRecordSeq) {
+ isOld = true;
+ }
+ }
+
+ if (!isOld && (frag instanceof HandshakeFragment)) {
+ HandshakeFragment hsf = (HandshakeFragment)frag;
+ isOld = (hsf.messageSeq <= precedingFlight.maxMessageSeq);
+ }
+
+ if (isOld) {
+ it.remove();
+ } else {
+ // Safe to break as items in the buffer are ordered.
+ break;
+ }
+ }
+
+ // discard retransmissions of the previous flight if any.
+ precedingFlight = null;
}
- boolean isEmpty() {
+ // Is a desired record?
+ //
+ // Check for retransmission and lost records.
+ private boolean isDesirable(RecordFragment rf) {
+ //
+ // Discard records old than the previous epoch.
+ //
+ int previousEpoch = nextRecordEpoch - 1;
+ if (rf.recordEpoch < previousEpoch) {
+ // Too old to use, discard this record.
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Too old epoch to use this record, discard it.");
+ }
+
+ return false;
+ }
+
+ //
+ // Allow retransmission of last flight of the previous epoch
+ //
+ // For example, the last server delivered flight for session
+ // resuming abbreviated handshaking consist three messages:
+ // ServerHello
+ // [ChangeCipherSpec]
+ // Finished
+ //
+ // The epoch number is incremented and the sequence number is reset
+ // if the ChangeCipherSpec is sent.
+ if (rf.recordEpoch == previousEpoch) {
+ boolean isDesired = true;
+ if (precedingFlight == null) {
+ isDesired = false;
+ } else {
+ if (rf instanceof HandshakeFragment) {
+ HandshakeFragment hsf = (HandshakeFragment)rf;
+ if (precedingFlight.minMessageSeq > hsf.messageSeq) {
+ isDesired = false;
+ }
+ } else if (rf.contentType == Record.ct_change_cipher_spec) {
+ // ChangeCipherSpec
+ if (precedingFlight.flightEpoch != rf.recordEpoch) {
+ isDesired = false;
+ }
+ } else { // ciphertext
+ if ((rf.recordEpoch < precedingFlight.maxRecordEpoch) ||
+ (rf.recordEpoch == precedingFlight.maxRecordEpoch &&
+ rf.recordSeq <= precedingFlight.maxRecordSeq)) {
+ isDesired = false;
+ }
+ }
+ }
+
+ if (!isDesired) {
+ // Too old to use, discard this retransmitted record
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Too old retransmission to use, discard it.");
+ }
+
+ return false;
+ }
+ } else if ((rf.recordEpoch == nextRecordEpoch) &&
+ (nextRecordSeq > rf.recordSeq)) {
+
+ // Previously disordered record for the current epoch.
+ //
+ // Should has been retransmitted. Discard this record.
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Lagging behind record (sequence), discard it.");
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean isEmpty() {
return (bufferedFragments.isEmpty() ||
(!flightIsReady && !needToCheckFlight) ||
(needToCheckFlight && !flightIsReady()));
@@ -708,12 +978,9 @@
Plaintext acquirePlaintext() {
if (bufferedFragments.isEmpty()) {
- // reset the flight
- if (flightIsReady) {
- flightIsReady = false;
- needToCheckFlight = false;
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("No received handshake messages");
}
-
return null;
}
@@ -721,27 +988,103 @@
// check the fligth status
flightIsReady = flightIsReady();
- // set for next flight
+ // Reset if this flight is ready.
if (flightIsReady) {
- flightTopMessageSeq = lastHandshakeFragment.messageSeq + 1;
- flightTopRecordSeq = -1;
+ // Retransmitted handshake messages are not needed for
+ // further handshaking processing.
+ if (handshakeFlight.isRetransmitOf(precedingFlight)) {
+ // cleanup
+ bufferedFragments.clear();
+
+ // Reset the next handshake flight.
+ resetHandshakeFlight(precedingFlight);
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Received a retransmission flight.");
+ }
+
+ return Plaintext.PLAINTEXT_NULL;
+ }
}
needToCheckFlight = false;
}
if (!flightIsReady) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("The handshake flight is not ready to use: " +
+ handshakeFlight.handshakeType);
+ }
return null;
}
RecordFragment rFrag = bufferedFragments.first();
+ Plaintext plaintext;
if (!rFrag.isCiphertext) {
// handshake message, or ChangeCipherSpec message
- return acquireHandshakeMessage();
+ plaintext = acquireHandshakeMessage();
+
+ // Reset the handshake flight.
+ if (bufferedFragments.isEmpty()) {
+ // Need not to backup the holes map. Clear up it at first.
+ handshakeFlight.holesMap.clear(); // cleanup holes map
+
+ // Update the preceding flight.
+ precedingFlight = (HandshakeFlight)handshakeFlight.clone();
+
+ // Reset the next handshake flight.
+ resetHandshakeFlight(precedingFlight);
+
+ if (expectCCSFlight &&
+ (precedingFlight.flightEpoch ==
+ HandshakeFlight.HF_UNKNOWN)) {
+ expectCCSFlight = false;
+ }
+ }
} else {
// a Finished message or other ciphertexts
- return acquireCachedMessage();
+ plaintext = acquireCachedMessage();
}
+
+ return plaintext;
+ }
+
+ //
+ // Reset the handshake flight from a previous one.
+ //
+ private void resetHandshakeFlight(HandshakeFlight prev) {
+ // Reset the next handshake flight.
+ handshakeFlight.handshakeType = HandshakeFlight.HF_UNKNOWN;
+ handshakeFlight.flightEpoch = prev.maxRecordEpoch;
+ if (prev.flightEpoch != prev.maxRecordEpoch) {
+ // a new epoch starts
+ handshakeFlight.minMessageSeq = 0;
+ } else {
+ // stay at the same epoch
+ //
+ // The minimal message sequence number will get updated if
+ // a flight retransmission happens.
+ handshakeFlight.minMessageSeq = prev.maxMessageSeq + 1;
+ }
+
+ // cleanup the maximum sequence number and epoch number.
+ //
+ // Note: actually, we need to do nothing because the reassembler
+ // of handshake messages will reset them properly even for
+ // retransmissions.
+ //
+ handshakeFlight.maxMessageSeq = 0;
+ handshakeFlight.maxRecordEpoch = handshakeFlight.flightEpoch;
+
+ // Record sequence number cannot wrap even for retransmissions.
+ handshakeFlight.maxRecordSeq = prev.maxRecordSeq + 1;
+
+ // cleanup holes map
+ handshakeFlight.holesMap.clear();
+
+ // Ready to accept new input record.
+ flightIsReady = false;
+ needToCheckFlight = false;
}
private Plaintext acquireCachedMessage() {
@@ -750,6 +1093,9 @@
if (readEpoch != rFrag.recordEpoch) {
if (readEpoch > rFrag.recordEpoch) {
// discard old records
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Discard old buffered ciphertext fragments.");
+ }
bufferedFragments.remove(rFrag); // popup the fragment
}
@@ -757,6 +1103,10 @@
if (flightIsReady) {
flightIsReady = false;
}
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Not yet ready to decrypt the cached fragments.");
+ }
return null;
}
@@ -768,9 +1118,8 @@
plaintextFragment = decrypt(readAuthenticator, readCipher,
rFrag.contentType, fragment, rFrag.recordEnS);
} catch (BadPaddingException bpe) {
- if (debug != null && Debug.isOn("ssl")) {
- System.out.println(Thread.currentThread().getName() +
- " discard invalid record: " + bpe);
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Discard invalid record: " + bpe);
}
// invalid, discard this record [section 4.1.2.7, RFC 6347]
@@ -782,7 +1131,6 @@
// beginning of the next flight) message. Need not to check
// any ChangeCipherSpec message.
if (rFrag.contentType == Record.ct_handshake) {
- HandshakeFragment finFrag = null;
while (plaintextFragment.remaining() > 0) {
HandshakeFragment hsFrag = parseHandshakeMessage(
rFrag.contentType,
@@ -792,66 +1140,31 @@
if (hsFrag == null) {
// invalid, discard this record
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.printHex(
+ "Invalid handshake fragment, discard it",
+ plaintextFragment);
+ }
return null;
}
- if (hsFrag.handshakeType == HandshakeMessage.ht_finished) {
- finFrag = hsFrag;
-
- // reset for the next flight
- this.flightType = (byte)0xFF;
- this.flightTopEpoch = rFrag.recordEpoch;
- this.flightTopMessageSeq = hsFrag.messageSeq + 1;
- this.flightTopRecordSeq = -1;
- } else {
- // reset the flight
- if (flightIsReady) {
- flightIsReady = false;
- }
- queueUpHandshake(hsFrag);
+ queueUpHandshake(hsFrag);
+ // The flight ready status (flightIsReady) should have
+ // been checked and updated for the Finished handshake
+ // message before the decryption. Please don't update
+ // flightIsReady for Finished messages.
+ if (hsFrag.handshakeType != HandshakeMessage.ht_finished) {
+ flightIsReady = false;
+ needToCheckFlight = true;
}
}
- this.nextRecordSeq = rFrag.recordSeq + 1;
- this.nextMessageSeq = 0;
-
- if (finFrag != null) {
- this.nextRecordEpoch = finFrag.recordEpoch;
- this.nextRecordSeq = finFrag.recordSeq + 1;
- this.nextMessageSeq = finFrag.messageSeq + 1;
-
- // Finished message does not fragment.
- byte[] recordFrag = new byte[finFrag.messageLength + 4];
- Plaintext plaintext = new Plaintext(finFrag.contentType,
- finFrag.majorVersion, finFrag.minorVersion,
- finFrag.recordEpoch, finFrag.recordSeq,
- ByteBuffer.wrap(recordFrag));
-
- // fill the handshake fragment of the record
- recordFrag[0] = finFrag.handshakeType;
- recordFrag[1] =
- (byte)((finFrag.messageLength >>> 16) & 0xFF);
- recordFrag[2] =
- (byte)((finFrag.messageLength >>> 8) & 0xFF);
- recordFrag[3] = (byte)(finFrag.messageLength & 0xFF);
-
- System.arraycopy(finFrag.fragment, 0,
- recordFrag, 4, finFrag.fragmentLength);
-
- // handshake hashing
- handshakeHashing(finFrag, plaintext);
-
- // input handshake finished
- handshakeFinished = true;
-
- return plaintext;
- } else {
- return acquirePlaintext();
- }
+ return acquirePlaintext();
} else {
return new Plaintext(rFrag.contentType,
rFrag.majorVersion, rFrag.minorVersion,
- rFrag.recordEpoch, rFrag.recordSeq,
+ rFrag.recordEpoch,
+ Authenticator.toLong(rFrag.recordEnS),
plaintextFragment);
}
}
@@ -861,17 +1174,23 @@
RecordFragment rFrag = bufferedFragments.first();
if (rFrag.contentType == Record.ct_change_cipher_spec) {
this.nextRecordEpoch = rFrag.recordEpoch + 1;
+
+ // For retransmissions, the next record sequence number is a
+ // positive value. Don't worry about it as the acquiring of
+ // the immediately followed Finished handshake message will
+ // reset the next record sequence number correctly.
this.nextRecordSeq = 0;
- // no change on next handshake message sequence number
- bufferedFragments.remove(rFrag); // popup the fragment
+ // Popup the fragment.
+ bufferedFragments.remove(rFrag);
// Reload if this message has been reserved for handshake hash.
handshakeHash.reload();
return new Plaintext(rFrag.contentType,
rFrag.majorVersion, rFrag.minorVersion,
- rFrag.recordEpoch, rFrag.recordSeq,
+ rFrag.recordEpoch,
+ Authenticator.toLong(rFrag.recordEnS),
ByteBuffer.wrap(rFrag.fragment));
} else { // rFrag.contentType == Record.ct_handshake
HandshakeFragment hsFrag = (HandshakeFragment)rFrag;
@@ -882,13 +1201,13 @@
// this.nextRecordEpoch = hsFrag.recordEpoch;
this.nextRecordSeq = hsFrag.recordSeq + 1;
- this.nextMessageSeq = hsFrag.messageSeq + 1;
// Note: may try to avoid byte array copy in the future.
byte[] recordFrag = new byte[hsFrag.messageLength + 4];
Plaintext plaintext = new Plaintext(hsFrag.contentType,
hsFrag.majorVersion, hsFrag.minorVersion,
- hsFrag.recordEpoch, hsFrag.recordSeq,
+ hsFrag.recordEpoch,
+ Authenticator.toLong(hsFrag.recordEnS),
ByteBuffer.wrap(recordFrag));
// fill the handshake fragment of the record
@@ -913,7 +1232,8 @@
byte[] recordFrag = new byte[hsFrag.messageLength + 4];
Plaintext plaintext = new Plaintext(hsFrag.contentType,
hsFrag.majorVersion, hsFrag.minorVersion,
- hsFrag.recordEpoch, hsFrag.recordSeq,
+ hsFrag.recordEpoch,
+ Authenticator.toLong(hsFrag.recordEnS),
ByteBuffer.wrap(recordFrag));
// fill the handshake fragment of the record
@@ -957,7 +1277,6 @@
handshakeHashing(hsFrag, plaintext);
this.nextRecordSeq = maxRecodeSN + 1;
- this.nextMessageSeq = msgSeq + 1;
return plaintext;
}
@@ -966,15 +1285,26 @@
boolean flightIsReady() {
- //
- // the ChangeCipherSpec/Finished flight
- //
- if (expectCCSFlight) {
- // Have the ChangeCipherSpec/Finished messages been received?
- return hasFinisedMessage(bufferedFragments);
- }
+ byte flightType = handshakeFlight.handshakeType;
+ if (flightType == HandshakeFlight.HF_UNKNOWN) {
+ //
+ // the ChangeCipherSpec/Finished flight
+ //
+ if (expectCCSFlight) {
+ // Have the ChangeCipherSpec/Finished flight been received?
+ boolean isReady = hasFinishedMessage(bufferedFragments);
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Has the final flight been received? " + isReady);
+ }
- if (flightType == (byte)0xFF) {
+ return isReady;
+ }
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("No flight is received yet.");
+ }
+
return false;
}
@@ -983,7 +1313,12 @@
(flightType == HandshakeMessage.ht_hello_verify_request)) {
// single handshake message flight
- return hasCompleted(holesMap.get(flightType));
+ boolean isReady = hasCompleted(flightType);
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Is the handshake message completed? " + isReady);
+ }
+
+ return isReady;
}
//
@@ -991,31 +1326,52 @@
//
if (flightType == HandshakeMessage.ht_server_hello) {
// Firstly, check the first flight handshake message.
- if (!hasCompleted(holesMap.get(flightType))) {
+ if (!hasCompleted(flightType)) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "The ServerHello message is not completed yet.");
+ }
+
return false;
}
//
// an abbreviated handshake
//
- if (isAbbreviatedHandshake) {
- // Ready to use the flight if received the
- // ChangeCipherSpec and Finished messages.
- return hasFinisedMessage(bufferedFragments);
+ if (hasFinishedMessage(bufferedFragments)) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("It's an abbreviated handshake.");
+ }
+
+ return true;
}
//
// a full handshake
//
- if (lastHandshakeFragment.handshakeType !=
- HandshakeMessage.ht_server_hello_done) {
+ List holes = handshakeFlight.holesMap.get(
+ HandshakeMessage.ht_server_hello_done);
+ if ((holes == null) || !holes.isEmpty()) {
// Not yet got the final message of the flight.
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Not yet got the ServerHelloDone message");
+ }
+
return false;
}
// Have all handshake message been received?
- return hasCompleted(bufferedFragments,
- flightTopMessageSeq, lastHandshakeFragment.messageSeq);
+ boolean isReady = hasCompleted(bufferedFragments,
+ handshakeFlight.minMessageSeq,
+ handshakeFlight.maxMessageSeq);
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Is the ServerHello flight (message " +
+ handshakeFlight.minMessageSeq + "-" +
+ handshakeFlight.maxMessageSeq +
+ ") completed? " + isReady);
+ }
+
+ return isReady;
}
//
@@ -1029,92 +1385,65 @@
(flightType == HandshakeMessage.ht_client_key_exchange)) {
// Firstly, check the first flight handshake message.
- if (!hasCompleted(holesMap.get(flightType))) {
- return false;
- }
+ if (!hasCompleted(flightType)) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "The ClientKeyExchange or client Certificate " +
+ "message is not completed yet.");
+ }
- if (!hasFinisedMessage(bufferedFragments)) {
- // not yet got the ChangeCipherSpec/Finished messages
return false;
}
- if (flightType == HandshakeMessage.ht_client_key_exchange) {
- // single handshake message flight
- return true;
+ // Is client CertificateVerify a mandatory message?
+ if (flightType == HandshakeMessage.ht_certificate) {
+ if (needClientVerify(bufferedFragments) &&
+ !hasCompleted(ht_certificate_verify)) {
+
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Not yet have the CertificateVerify message");
+ }
+
+ return false;
+ }
}
- //
- // flightType == HandshakeMessage.ht_certificate
- //
- // We don't support certificates containing fixed
- // Diffie-Hellman parameters. Therefore, CertificateVerify
- // message is required if client Certificate message presents.
- //
- if (lastHandshakeFragment.handshakeType !=
- HandshakeMessage.ht_certificate_verify) {
- // Not yet got the final message of the flight.
+ if (!hasFinishedMessage(bufferedFragments)) {
+ // not yet have the ChangeCipherSpec/Finished messages
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Not yet have the ChangeCipherSpec and " +
+ "Finished messages");
+ }
+
return false;
}
// Have all handshake message been received?
- return hasCompleted(bufferedFragments,
- flightTopMessageSeq, lastHandshakeFragment.messageSeq);
+ boolean isReady = hasCompleted(bufferedFragments,
+ handshakeFlight.minMessageSeq,
+ handshakeFlight.maxMessageSeq);
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Is the ClientKeyExchange flight (message " +
+ handshakeFlight.minMessageSeq + "-" +
+ handshakeFlight.maxMessageSeq +
+ ") completed? " + isReady);
+ }
+
+ return isReady;
}
//
// Otherwise, need to receive more handshake messages.
//
- return false;
- }
-
- private boolean isSessionResuming(
- byte[] fragment, byte[] prevSid) throws SSLException {
-
- // As the first fragment of ServerHello should be big enough
- // to hold the session_id field, need not to worry about the
- // fragmentation here.
- if ((fragment == null) || (fragment.length < 38)) {
- // 38: the minimal ServerHello body length
- throw new SSLException(
- "Invalid ServerHello message: no sufficient data");
- }
-
- int sidLen = fragment[34]; // 34: the length field
- if (sidLen > 32) { // opaque SessionID<0..32>
- throw new SSLException(
- "Invalid ServerHello message: invalid session id");
- }
-
- if (fragment.length < 38 + sidLen) {
- throw new SSLException(
- "Invalid ServerHello message: no sufficient data");
- }
-
- if (sidLen != 0 && (prevSid.length == sidLen)) {
- // may be a session-resuming handshake
- for (int i = 0; i < sidLen; i++) {
- if (prevSid[i] != fragment[35 + i]) {
- // 35: the session identifier
- return false;
- }
- }
-
- return true;
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log("Need to receive more handshake messages");
}
return false;
}
- private byte[] getSessionID(byte[] fragment) {
- // The validity has been checked in the call to isSessionResuming().
- int sidLen = fragment[34]; // 34: the sessionID length field
-
- byte[] temporary = new byte[sidLen];
- System.arraycopy(fragment, 35, temporary, 0, sidLen);
-
- return temporary;
- }
-
// Looking for the ChangeCipherSpec and Finished messages.
//
// As the cached Finished message should be a ciphertext, we don't
@@ -1122,8 +1451,7 @@
// to the spec of TLS/DTLS handshaking, a Finished message is always
// sent immediately after a ChangeCipherSpec message. The first
// ciphertext handshake message should be the expected Finished message.
- private boolean hasFinisedMessage(
- Set fragments) {
+ private boolean hasFinishedMessage(Set fragments) {
boolean hasCCS = false;
boolean hasFin = false;
@@ -1147,7 +1475,35 @@
return hasFin && hasCCS;
}
- private boolean hasCompleted(List holes) {
+ // Is client CertificateVerify a mandatory message?
+ //
+ // In the current implementation, client CertificateVerify is a
+ // mandatory message if the client Certificate is not empty.
+ private boolean needClientVerify(Set fragments) {
+
+ // The caller should have checked the completion of the first
+ // present handshake message. Need not to check it again.
+ for (RecordFragment rFrag : fragments) {
+ if ((rFrag.contentType != Record.ct_handshake) ||
+ rFrag.isCiphertext) {
+ break;
+ }
+
+ HandshakeFragment hsFrag = (HandshakeFragment)rFrag;
+ if (hsFrag.handshakeType != HandshakeMessage.ht_certificate) {
+ continue;
+ }
+
+ return (rFrag.fragment != null) &&
+ (rFrag.fragment.length > DTLSRecord.minCertPlaintextSize);
+ }
+
+ return false;
+ }
+
+ private boolean hasCompleted(byte handshakeType) {
+ List holes =
+ handshakeFlight.holesMap.get(handshakeType);
if (holes == null) {
// not yet received this kind of handshake message
return false;
@@ -1173,7 +1529,7 @@
continue;
} else if (hsFrag.messageSeq == (presentMsgSeq + 1)) {
// check the completion of the handshake message
- if (!hasCompleted(holesMap.get(hsFrag.handshakeType))) {
+ if (!hasCompleted(hsFrag.handshakeType)) {
return false;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DTLSOutputRecord.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -279,6 +279,16 @@
fragmenter = null;
}
+ @Override
+ void launchRetransmission() {
+ // Note: Please don't retransmit if there are handshake messages
+ // or alerts waiting in the queue.
+ if (((alertMemos == null) || alertMemos.isEmpty()) &&
+ (fragmenter != null) && fragmenter.isRetransmittable()) {
+ fragmenter.setRetransmission();
+ }
+ }
+
// buffered record fragment
private static class RecordMemo {
byte contentType;
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/DTLSRecord.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/DTLSRecord.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/DTLSRecord.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,4 +84,18 @@
+ maxPadding // padding
+ maxMacSize; // MAC
+ /*
+ * Minimum record size of Certificate handshake message.
+ * Client sends a certificate message containing no certificates if no
+ * suitable certificate is available. That is, the certificate_list
+ * structure has a length of zero.
+ *
+ * struct {
+ * ASN.1Cert certificate_list<0..2^24-1>;
+ * } Certificate;
+ */
+ static final int minCertPlaintextSize =
+ headerSize // record header
+ + handshakeHeaderSize // handshake header
+ + 3; // cert list length
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/Debug.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Debug.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -145,6 +145,13 @@
}
/**
+ * Print a message to stdout.
+ */
+ static void log(String message) {
+ System.out.println(Thread.currentThread().getName() + ": " + message);
+ }
+
+ /**
* print a blank line to stderr that is prefixed with the prefix.
*/
@@ -156,7 +163,6 @@
/**
* print a message to stderr that is prefixed with the prefix.
*/
-
public static void println(String prefix, String message)
{
System.err.println(prefix + ": "+message);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/OutputRecord.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/OutputRecord.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/OutputRecord.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,6 +194,11 @@
// blank
}
+ // apply to DTLS SSLEngine
+ void launchRetransmission() {
+ // blank
+ }
+
@Override
public synchronized void close() throws IOException {
if (!isClosed) {
@@ -224,6 +229,9 @@
sequenceNumber = authenticator.sequenceNumber();
}
+ // The sequence number may be shared for different purpose.
+ boolean sharedSequenceNumber = false;
+
// "flip" but skip over header again, add MAC & encrypt
if (authenticator instanceof MAC) {
MAC signer = (MAC)authenticator;
@@ -243,6 +251,11 @@
// reset the position and limit
destination.limit(destination.position());
destination.position(dstContent);
+
+ // The signer has used and increased the sequence number.
+ if (isDTLS) {
+ sharedSequenceNumber = true;
+ }
}
}
@@ -261,6 +274,11 @@
// Encrypt may pad, so again the limit may be changed.
encCipher.encrypt(destination, dstLim);
+
+ // The cipher has used and increased the sequence number.
+ if (isDTLS && encCipher.isAEADMode()) {
+ sharedSequenceNumber = true;
+ }
} else {
destination.position(destination.limit());
}
@@ -290,8 +308,10 @@
destination.put(headerOffset + 11, (byte)(fragLen >> 8));
destination.put(headerOffset + 12, (byte)fragLen);
- // Increase the sequence number for next use.
- authenticator.increaseSequenceNumber();
+ // Increase the sequence number for next use if it is not shared.
+ if (!sharedSequenceNumber) {
+ authenticator.increaseSequenceNumber();
+ }
}
// Update destination position to reflect the amount of data produced.
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/Plaintext.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Plaintext.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Plaintext.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
byte majorVersion;
byte minorVersion;
int recordEpoch; // incremented on every cipher state change
- long recordSN;
+ long recordSN; // contains epcoh number (epoch | sequence)
ByteBuffer fragment; // null if need to be reassembled
HandshakeStatus handshakeStatus; // null if not used or not handshaking
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -994,7 +994,22 @@
// plainText should never be null for TLS protocols
HandshakeStatus hsStatus = null;
- if (!isDTLS || plainText != null) {
+ if (plainText == Plaintext.PLAINTEXT_NULL) {
+ // Only happens for DTLS protocols.
+ //
+ // Received a retransmitted flight, and need to retransmit the
+ // previous delivered handshake flight messages.
+ if (enableRetransmissions) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Retransmit the previous handshake flight messages.");
+ }
+
+ synchronized (this) {
+ outputRecord.launchRetransmission();
+ }
+ } // Otherwise, discard the retransmitted flight.
+ } else if (!isDTLS || plainText != null) {
hsStatus = processInputRecord(plainText, appData, offset, length);
}
@@ -1003,7 +1018,7 @@
}
if (plainText == null) {
- plainText = new Plaintext();
+ plainText = Plaintext.PLAINTEXT_NULL;
}
plainText.handshakeStatus = hsStatus;
@@ -1378,7 +1393,8 @@
// Acquire the buffered to-be-delivered records or retransmissions.
//
// May have buffered records, or need retransmission if handshaking.
- if (!outputRecord.isEmpty() || (handshaker != null)) {
+ if (!outputRecord.isEmpty() ||
+ (enableRetransmissions && handshaker != null)) {
ciphertext = outputRecord.acquireCiphertext(netData);
}
@@ -1403,13 +1419,36 @@
HandshakeStatus hsStatus = null;
Ciphertext.RecordType recordType = ciphertext.recordType;
- if ((handshaker != null) &&
- (recordType.contentType == Record.ct_handshake) &&
- (recordType.handshakeType == HandshakeMessage.ht_finished) &&
- handshaker.isDone() && outputRecord.isEmpty()) {
+ if ((recordType.contentType == Record.ct_handshake) &&
+ (recordType.handshakeType == HandshakeMessage.ht_finished) &&
+ outputRecord.isEmpty()) {
+
+ if (handshaker == null) {
+ hsStatus = HandshakeStatus.FINISHED;
+ } else if (handshaker.isDone()) {
+ hsStatus = finishHandshake();
+ connectionState = cs_DATA;
- hsStatus = finishHandshake();
- connectionState = cs_DATA;
+ // Retransmit the last flight twice.
+ //
+ // The application data transactions may begin immediately
+ // after the last flight. If the last flight get lost, the
+ // application data may be discarded accordingly. As could
+ // be an issue for some applications. This impact can be
+ // mitigated by sending the last fligth twice.
+ if (isDTLS && enableRetransmissions) {
+ if (debug != null && Debug.isOn("verbose")) {
+ Debug.log(
+ "Retransmit the last flight messages.");
+ }
+
+ synchronized (this) {
+ outputRecord.launchRetransmission();
+ }
+
+ hsStatus = HandshakeStatus.NEED_WRAP;
+ }
+ }
} // Otherwise, the followed call to getHSStatus() will help.
/*
@@ -1676,12 +1715,17 @@
synchronized void fatal(byte description, String diagnostic)
throws SSLException {
- fatal(description, diagnostic, null);
+ fatal(description, diagnostic, null, false);
}
synchronized void fatal(byte description, Throwable cause)
throws SSLException {
- fatal(description, null, cause);
+ fatal(description, null, cause, false);
+ }
+
+ synchronized void fatal(byte description, String diagnostic,
+ Throwable cause) throws SSLException {
+ fatal(description, diagnostic, cause, false);
}
/*
@@ -1693,12 +1737,12 @@
* levels which then call here. This code needs to determine
* if one of the lower levels has already started the process.
*
- * We won't worry about Error's, if we have one of those,
+ * We won't worry about Errors, if we have one of those,
* we're in worse trouble. Note: the networking code doesn't
* deal with Errors either.
*/
synchronized void fatal(byte description, String diagnostic,
- Throwable cause) throws SSLException {
+ Throwable cause, boolean recvFatalAlert) throws SSLException {
/*
* If we have no further information, make a general-purpose
@@ -1759,10 +1803,11 @@
}
/*
- * If we haven't even started handshaking yet, no need
- * to generate the fatal close alert.
+ * If we haven't even started handshaking yet, or we are the
+ * recipient of a fatal alert, no need to generate a fatal close
+ * alert.
*/
- if (oldState != cs_START) {
+ if (oldState != cs_START && !recvFatalAlert) {
sendAlert(Alerts.alert_fatal, description);
}
@@ -1802,10 +1847,6 @@
byte level = fragment.get();
byte description = fragment.get();
- if (description == -1) { // check for short message
- fatal(Alerts.alert_illegal_parameter, "Short alert message");
- }
-
if (debug != null && (Debug.isOn("record") ||
Debug.isOn("handshake"))) {
synchronized (System.out) {
@@ -1823,7 +1864,9 @@
}
if (level == Alerts.alert_warning) {
- if (description == Alerts.alert_close_notify) {
+ if (description == -1) { // check for short message
+ fatal(Alerts.alert_illegal_parameter, "Short alert message");
+ } else if (description == Alerts.alert_close_notify) {
if (connectionState == cs_HANDSHAKE) {
fatal(Alerts.alert_unexpected_message,
"Received close_notify during handshake");
@@ -1846,10 +1889,14 @@
} else { // fatal or unknown level
String reason = "Received fatal alert: "
+ Alerts.alertDescription(description);
- if (closeReason == null) {
- closeReason = Alerts.getSSLException(description, reason);
- }
- fatal(Alerts.alert_unexpected_message, reason);
+
+ // The inbound and outbound queues will be closed as part of
+ // the call to fatal. The handhaker to needs to be set to null
+ // so subsequent calls to getHandshakeStatus will return
+ // NOT_HANDSHAKING.
+ handshaker = null;
+ Throwable cause = Alerts.getSSLException(description, reason);
+ fatal(description, null, cause, true);
}
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Fri Nov 11 16:44:36 2016 +0100
@@ -558,73 +558,6 @@
applicationProtocol = "";
}
- // cookie exchange
- if (isDTLS) {
- HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
- if ((mesg.cookie == null) || (mesg.cookie.length == 0) ||
- (!hcMgr.isValid(mesg))) {
-
- //
- // Perform cookie exchange for DTLS handshaking if no cookie
- // or the cookie is invalid in the ClientHello message.
- //
- HelloVerifyRequest m0 = new HelloVerifyRequest(hcMgr, mesg);
-
- if (debug != null && Debug.isOn("handshake")) {
- m0.print(System.out);
- }
-
- m0.write(output);
- handshakeState.update(m0, resumingSession);
- output.flush();
-
- return;
- }
- }
-
- /*
- * FIRST, construct the ServerHello using the options and priorities
- * from the ClientHello. Update the (pending) cipher spec as we do
- * so, and save the client's version to protect against rollback
- * attacks.
- *
- * There are a bunch of minor tasks here, and one major one: deciding
- * if the short or the full handshake sequence will be used.
- */
- ServerHello m1 = new ServerHello();
-
- clientRequestedVersion = mesg.protocolVersion;
-
- // select a proper protocol version.
- ProtocolVersion selectedVersion =
- selectProtocolVersion(clientRequestedVersion);
- if (selectedVersion == null ||
- selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
- fatalSE(Alerts.alert_handshake_failure,
- "Client requested protocol " + clientRequestedVersion +
- " not enabled or not supported");
- }
-
- handshakeHash.protocolDetermined(selectedVersion);
- setVersion(selectedVersion);
-
- m1.protocolVersion = protocolVersion;
-
- //
- // random ... save client and server values for later use
- // in computing the master secret (from pre-master secret)
- // and thence the other crypto keys.
- //
- // NOTE: this use of three inputs to generating _each_ set
- // of ciphers slows things down, but it does increase the
- // security since each connection in the session can hold
- // its own authenticated (and strong) keys. One could make
- // creation of a session a rare thing...
- //
- clnt_random = mesg.clnt_random;
- svr_random = new RandomCookie(sslContext.getSecureRandom());
- m1.svr_random = svr_random;
-
session = null; // forget about the current session
//
// Here we go down either of two paths: (a) the fast one, where
@@ -732,6 +665,73 @@
}
} // else client did not try to resume
+ // cookie exchange
+ if (isDTLS && !resumingSession) {
+ HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
+ if ((mesg.cookie == null) || (mesg.cookie.length == 0) ||
+ (!hcMgr.isValid(mesg))) {
+
+ //
+ // Perform cookie exchange for DTLS handshaking if no cookie
+ // or the cookie is invalid in the ClientHello message.
+ //
+ HelloVerifyRequest m0 = new HelloVerifyRequest(hcMgr, mesg);
+
+ if (debug != null && Debug.isOn("handshake")) {
+ m0.print(System.out);
+ }
+
+ m0.write(output);
+ handshakeState.update(m0, resumingSession);
+ output.flush();
+
+ return;
+ }
+ }
+
+ /*
+ * FIRST, construct the ServerHello using the options and priorities
+ * from the ClientHello. Update the (pending) cipher spec as we do
+ * so, and save the client's version to protect against rollback
+ * attacks.
+ *
+ * There are a bunch of minor tasks here, and one major one: deciding
+ * if the short or the full handshake sequence will be used.
+ */
+ ServerHello m1 = new ServerHello();
+
+ clientRequestedVersion = mesg.protocolVersion;
+
+ // select a proper protocol version.
+ ProtocolVersion selectedVersion =
+ selectProtocolVersion(clientRequestedVersion);
+ if (selectedVersion == null ||
+ selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Client requested protocol " + clientRequestedVersion +
+ " not enabled or not supported");
+ }
+
+ handshakeHash.protocolDetermined(selectedVersion);
+ setVersion(selectedVersion);
+
+ m1.protocolVersion = protocolVersion;
+
+ //
+ // random ... save client and server values for later use
+ // in computing the master secret (from pre-master secret)
+ // and thence the other crypto keys.
+ //
+ // NOTE: this use of three inputs to generating _each_ set
+ // of ciphers slows things down, but it does increase the
+ // security since each connection in the session can hold
+ // its own authenticated (and strong) keys. One could make
+ // creation of a session a rare thing...
+ //
+ clnt_random = mesg.clnt_random;
+ svr_random = new RandomCookie(sslContext.getSecureRandom());
+ m1.svr_random = svr_random;
+
//
// If client hasn't specified a session we can resume, start a
// new one and choose its cipher suite and compression options.
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/text/BreakDictionary.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/BreakDictionary.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+package sun.text;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.MissingResourceException;
+import sun.text.CompactByteArray;
+import sun.text.SupplementaryCharacterData;
+
+/**
+ * This is the class that represents the list of known words used by
+ * DictionaryBasedBreakIterator. The conceptual data structure used
+ * here is a trie: there is a node hanging off the root node for every
+ * letter that can start a word. Each of these nodes has a node hanging
+ * off of it for every letter that can be the second letter of a word
+ * if this node is the first letter, and so on. The trie is represented
+ * as a two-dimensional array that can be treated as a table of state
+ * transitions. Indexes are used to compress this array, taking
+ * advantage of the fact that this array will always be very sparse.
+ */
+class BreakDictionary {
+
+ //=========================================================================
+ // data members
+ //=========================================================================
+
+ /**
+ * The version of the dictionary that was read in.
+ */
+ private static int supportedVersion = 1;
+
+ /**
+ * Maps from characters to column numbers. The main use of this is to
+ * avoid making room in the array for empty columns.
+ */
+ private CompactByteArray columnMap = null;
+ private SupplementaryCharacterData supplementaryCharColumnMap = null;
+
+ /**
+ * The number of actual columns in the table
+ */
+ private int numCols;
+
+ /**
+ * Columns are organized into groups of 32. This says how many
+ * column groups. (We could calculate this, but we store the
+ * value to avoid having to repeatedly calculate it.)
+ */
+ private int numColGroups;
+
+ /**
+ * The actual compressed state table. Each conceptual row represents
+ * a state, and the cells in it contain the row numbers of the states
+ * to transition to for each possible letter. 0 is used to indicate
+ * an illegal combination of letters (i.e., the error state). The
+ * table is compressed by eliminating all the unpopulated (i.e., zero)
+ * cells. Multiple conceptual rows can then be doubled up in a single
+ * physical row by sliding them up and possibly shifting them to one
+ * side or the other so the populated cells don't collide. Indexes
+ * are used to identify unpopulated cells and to locate populated cells.
+ */
+ private short[] table = null;
+
+ /**
+ * This index maps logical row numbers to physical row numbers
+ */
+ private short[] rowIndex = null;
+
+ /**
+ * A bitmap is used to tell which cells in the comceptual table are
+ * populated. This array contains all the unique bit combinations
+ * in that bitmap. If the table is more than 32 columns wide,
+ * successive entries in this array are used for a single row.
+ */
+ private int[] rowIndexFlags = null;
+
+ /**
+ * This index maps from a logical row number into the bitmap table above.
+ * (This keeps us from storing duplicate bitmap combinations.) Since there
+ * are a lot of rows with only one populated cell, instead of wasting space
+ * in the bitmap table, we just store a negative number in this index for
+ * rows with one populated cell. The absolute value of that number is
+ * the column number of the populated cell.
+ */
+ private short[] rowIndexFlagsIndex = null;
+
+ /**
+ * For each logical row, this index contains a constant that is added to
+ * the logical column number to get the physical column number
+ */
+ private byte[] rowIndexShifts = null;
+
+ //=========================================================================
+ // deserialization
+ //=========================================================================
+
+ BreakDictionary(String dictionaryName, byte[] dictionaryData) {
+ try {
+ setupDictionary(dictionaryName, dictionaryData);
+ } catch (BufferUnderflowException bue) {
+ MissingResourceException e;
+ e = new MissingResourceException("Corrupted dictionary data",
+ dictionaryName, "");
+ e.initCause(bue);
+ throw e;
+ }
+ }
+
+ private void setupDictionary(String dictionaryName, byte[] dictionaryData) {
+ ByteBuffer bb = ByteBuffer.wrap(dictionaryData);
+
+ // check version
+ int version = bb.getInt();
+ if (version != supportedVersion) {
+ throw new MissingResourceException("Dictionary version(" + version + ") is unsupported",
+ dictionaryName, "");
+ }
+
+ // Check data size
+ int len = bb.getInt();
+ if (bb.position() + len != bb.limit()) {
+ throw new MissingResourceException("Dictionary size is wrong: " + bb.limit(),
+ dictionaryName, "");
+ }
+
+ // read in the column map for BMP characteres (this is serialized in
+ // its internal form: an index array followed by a data array)
+ len = bb.getInt();
+ short[] temp = new short[len];
+ for (int i = 0; i < len; i++) {
+ temp[i] = bb.getShort();
+ }
+ len = bb.getInt();
+ byte[] temp2 = new byte[len];
+ bb.get(temp2);
+ columnMap = new CompactByteArray(temp, temp2);
+
+ // read in numCols and numColGroups
+ numCols = bb.getInt();
+ numColGroups = bb.getInt();
+
+ // read in the row-number index
+ len = bb.getInt();
+ rowIndex = new short[len];
+ for (int i = 0; i < len; i++) {
+ rowIndex[i] = bb.getShort();
+ }
+
+ // load in the populated-cells bitmap: index first, then bitmap list
+ len = bb.getInt();
+ rowIndexFlagsIndex = new short[len];
+ for (int i = 0; i < len; i++) {
+ rowIndexFlagsIndex[i] = bb.getShort();
+ }
+ len = bb.getInt();
+ rowIndexFlags = new int[len];
+ for (int i = 0; i < len; i++) {
+ rowIndexFlags[i] = bb.getInt();
+ }
+
+ // load in the row-shift index
+ len = bb.getInt();
+ rowIndexShifts = new byte[len];
+ bb.get(rowIndexShifts);
+
+ // load in the actual state table
+ len = bb.getInt();
+ table = new short[len];
+ for (int i = 0; i < len; i++) {
+ table[i] = bb.getShort();
+ }
+
+ // finally, prepare the column map for supplementary characters
+ len = bb.getInt();
+ int[] temp3 = new int[len];
+ for (int i = 0; i < len; i++) {
+ temp3[i] = bb.getInt();
+ }
+ assert bb.position() == bb.limit();
+
+ supplementaryCharColumnMap = new SupplementaryCharacterData(temp3);
+ }
+
+ //=========================================================================
+ // access to the words
+ //=========================================================================
+
+ /**
+ * Uses the column map to map the character to a column number, then
+ * passes the row and column number to getNextState()
+ * @param row The current state
+ * @param ch The character whose column we're interested in
+ * @return The new state to transition to
+ */
+ public final short getNextStateFromCharacter(int row, int ch) {
+ int col;
+ if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ col = columnMap.elementAt((char)ch);
+ } else {
+ col = supplementaryCharColumnMap.getValue(ch);
+ }
+ return getNextState(row, col);
+ }
+
+ /**
+ * Returns the value in the cell with the specified (logical) row and
+ * column numbers. In DictionaryBasedBreakIterator, the row number is
+ * a state number, the column number is an input, and the return value
+ * is the row number of the new state to transition to. (0 is the
+ * "error" state, and -1 is the "end of word" state in a dictionary)
+ * @param row The row number of the current state
+ * @param col The column number of the input character (0 means "not a
+ * dictionary character")
+ * @return The row number of the new state to transition to
+ */
+ public final short getNextState(int row, int col) {
+ if (cellIsPopulated(row, col)) {
+ // we map from logical to physical row number by looking up the
+ // mapping in rowIndex; we map from logical column number to
+ // physical column number by looking up a shift value for this
+ // logical row and offsetting the logical column number by
+ // the shift amount. Then we can use internalAt() to actually
+ // get the value out of the table.
+ return internalAt(rowIndex[row], col + rowIndexShifts[row]);
+ }
+ else {
+ return 0;
+ }
+ }
+
+ /**
+ * Given (logical) row and column numbers, returns true if the
+ * cell in that position is populated
+ */
+ private boolean cellIsPopulated(int row, int col) {
+ // look up the entry in the bitmap index for the specified row.
+ // If it's a negative number, it's the column number of the only
+ // populated cell in the row
+ if (rowIndexFlagsIndex[row] < 0) {
+ return col == -rowIndexFlagsIndex[row];
+ }
+
+ // if it's a positive number, it's the offset of an entry in the bitmap
+ // list. If the table is more than 32 columns wide, the bitmap is stored
+ // successive entries in the bitmap list, so we have to divide the column
+ // number by 32 and offset the number we got out of the index by the result.
+ // Once we have the appropriate piece of the bitmap, test the appropriate
+ // bit and return the result.
+ else {
+ int flags = rowIndexFlags[rowIndexFlagsIndex[row] + (col >> 5)];
+ return (flags & (1 << (col & 0x1f))) != 0;
+ }
+ }
+
+ /**
+ * Implementation of getNextState() when we know the specified cell is
+ * populated.
+ * @param row The PHYSICAL row number of the cell
+ * @param col The PHYSICAL column number of the cell
+ * @return The value stored in the cell
+ */
+ private short internalAt(int row, int col) {
+ // the table is a one-dimensional array, so this just does the math necessary
+ // to treat it as a two-dimensional array (we don't just use a two-dimensional
+ // array because two-dimensional arrays are inefficient in Java)
+ return table[row * numCols + col];
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/text/DictionaryBasedBreakIterator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/DictionaryBasedBreakIterator.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+
+package sun.text;
+
+import java.text.CharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * A subclass of RuleBasedBreakIterator that adds the ability to use a dictionary
+ * to further subdivide ranges of text beyond what is possible using just the
+ * state-table-based algorithm. This is necessary, for example, to handle
+ * word and line breaking in Thai, which doesn't use spaces between words. The
+ * state-table-based algorithm used by RuleBasedBreakIterator is used to divide
+ * up text as far as possible, and then contiguous ranges of letters are
+ * repeatedly compared against a list of known words (i.e., the dictionary)
+ * to divide them up into words.
+ *
+ * DictionaryBasedBreakIterator uses the same rule language as RuleBasedBreakIterator,
+ * but adds one more special substitution name: <dictionary>. This substitution
+ * name is used to identify characters in words in the dictionary. The idea is that
+ * if the iterator passes over a chunk of text that includes two or more characters
+ * in a row that are included in <dictionary>, it goes back through that range and
+ * derives additional break positions (if possible) using the dictionary.
+ *
+ * DictionaryBasedBreakIterator is also constructed with the filename of a dictionary
+ * file. It follows a prescribed search path to locate the dictionary (right now,
+ * it looks for it in /com/ibm/text/resources in each directory in the classpath,
+ * and won't find it in JAR files, but this location is likely to change). The
+ * dictionary file is in a serialized binary format. We have a very primitive (and
+ * slow) BuildDictionaryFile utility for creating dictionary files, but aren't
+ * currently making it public. Contact us for help.
+ */
+public class DictionaryBasedBreakIterator extends RuleBasedBreakIterator {
+
+ /**
+ * a list of known words that is used to divide up contiguous ranges of letters,
+ * stored in a compressed, indexed, format that offers fast access
+ */
+ private BreakDictionary dictionary;
+
+ /**
+ * a list of flags indicating which character categories are contained in
+ * the dictionary file (this is used to determine which ranges of characters
+ * to apply the dictionary to)
+ */
+ private boolean[] categoryFlags;
+
+ /**
+ * a temporary hiding place for the number of dictionary characters in the
+ * last range passed over by next()
+ */
+ private int dictionaryCharCount;
+
+ /**
+ * when a range of characters is divided up using the dictionary, the break
+ * positions that are discovered are stored here, preventing us from having
+ * to use either the dictionary or the state table again until the iterator
+ * leaves this range of text
+ */
+ private int[] cachedBreakPositions;
+
+ /**
+ * if cachedBreakPositions is not null, this indicates which item in the
+ * cache the current iteration position refers to
+ */
+ private int positionInCache;
+
+ /**
+ * Constructs a DictionaryBasedBreakIterator.
+ *
+ * @param ruleFile the name of the rule data file
+ * @param ruleData the rule data loaded from the rule data file
+ * @param dictionaryFile the name of the dictionary file
+ * @param dictionartData the dictionary data loaded from the dictionary file
+ * @throws MissingResourceException if rule data or dictionary initialization failed
+ */
+ public DictionaryBasedBreakIterator(String ruleFile, byte[] ruleData,
+ String dictionaryFile, byte[] dictionaryData) {
+ super(ruleFile, ruleData);
+ byte[] tmp = super.getAdditionalData();
+ if (tmp != null) {
+ prepareCategoryFlags(tmp);
+ super.setAdditionalData(null);
+ }
+ dictionary = new BreakDictionary(dictionaryFile, dictionaryData);
+ }
+
+ private void prepareCategoryFlags(byte[] data) {
+ categoryFlags = new boolean[data.length];
+ for (int i = 0; i < data.length; i++) {
+ categoryFlags[i] = (data[i] == (byte)1) ? true : false;
+ }
+ }
+
+ @Override
+ public void setText(CharacterIterator newText) {
+ super.setText(newText);
+ cachedBreakPositions = null;
+ dictionaryCharCount = 0;
+ positionInCache = 0;
+ }
+
+ /**
+ * Sets the current iteration position to the beginning of the text.
+ * (i.e., the CharacterIterator's starting offset).
+ * @return The offset of the beginning of the text.
+ */
+ @Override
+ public int first() {
+ cachedBreakPositions = null;
+ dictionaryCharCount = 0;
+ positionInCache = 0;
+ return super.first();
+ }
+
+ /**
+ * Sets the current iteration position to the end of the text.
+ * (i.e., the CharacterIterator's ending offset).
+ * @return The text's past-the-end offset.
+ */
+ @Override
+ public int last() {
+ cachedBreakPositions = null;
+ dictionaryCharCount = 0;
+ positionInCache = 0;
+ return super.last();
+ }
+
+ /**
+ * Advances the iterator one step backwards.
+ * @return The position of the last boundary position before the
+ * current iteration position
+ */
+ @Override
+ public int previous() {
+ CharacterIterator text = getText();
+
+ // if we have cached break positions and we're still in the range
+ // covered by them, just move one step backward in the cache
+ if (cachedBreakPositions != null && positionInCache > 0) {
+ --positionInCache;
+ text.setIndex(cachedBreakPositions[positionInCache]);
+ return cachedBreakPositions[positionInCache];
+ }
+
+ // otherwise, dump the cache and use the inherited previous() method to move
+ // backward. This may fill up the cache with new break positions, in which
+ // case we have to mark our position in the cache
+ else {
+ cachedBreakPositions = null;
+ int result = super.previous();
+ if (cachedBreakPositions != null) {
+ positionInCache = cachedBreakPositions.length - 2;
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Sets the current iteration position to the last boundary position
+ * before the specified position.
+ * @param offset The position to begin searching from
+ * @return The position of the last boundary before "offset"
+ */
+ @Override
+ public int preceding(int offset) {
+ CharacterIterator text = getText();
+ checkOffset(offset, text);
+
+ // if we have no cached break positions, or "offset" is outside the
+ // range covered by the cache, we can just call the inherited routine
+ // (which will eventually call other routines in this class that may
+ // refresh the cache)
+ if (cachedBreakPositions == null || offset <= cachedBreakPositions[0] ||
+ offset > cachedBreakPositions[cachedBreakPositions.length - 1]) {
+ cachedBreakPositions = null;
+ return super.preceding(offset);
+ }
+
+ // on the other hand, if "offset" is within the range covered by the cache,
+ // then all we have to do is search the cache for the last break position
+ // before "offset"
+ else {
+ positionInCache = 0;
+ while (positionInCache < cachedBreakPositions.length
+ && offset > cachedBreakPositions[positionInCache]) {
+ ++positionInCache;
+ }
+ --positionInCache;
+ text.setIndex(cachedBreakPositions[positionInCache]);
+ return text.getIndex();
+ }
+ }
+
+ /**
+ * Sets the current iteration position to the first boundary position after
+ * the specified position.
+ * @param offset The position to begin searching forward from
+ * @return The position of the first boundary after "offset"
+ */
+ @Override
+ public int following(int offset) {
+ CharacterIterator text = getText();
+ checkOffset(offset, text);
+
+ // if we have no cached break positions, or if "offset" is outside the
+ // range covered by the cache, then dump the cache and call our
+ // inherited following() method. This will call other methods in this
+ // class that may refresh the cache.
+ if (cachedBreakPositions == null || offset < cachedBreakPositions[0] ||
+ offset >= cachedBreakPositions[cachedBreakPositions.length - 1]) {
+ cachedBreakPositions = null;
+ return super.following(offset);
+ }
+
+ // on the other hand, if "offset" is within the range covered by the
+ // cache, then just search the cache for the first break position
+ // after "offset"
+ else {
+ positionInCache = 0;
+ while (positionInCache < cachedBreakPositions.length
+ && offset >= cachedBreakPositions[positionInCache]) {
+ ++positionInCache;
+ }
+ text.setIndex(cachedBreakPositions[positionInCache]);
+ return text.getIndex();
+ }
+ }
+
+ /**
+ * This is the implementation function for next().
+ */
+ @Override
+ protected int handleNext() {
+ CharacterIterator text = getText();
+
+ // if there are no cached break positions, or if we've just moved
+ // off the end of the range covered by the cache, we have to dump
+ // and possibly regenerate the cache
+ if (cachedBreakPositions == null ||
+ positionInCache == cachedBreakPositions.length - 1) {
+
+ // start by using the inherited handleNext() to find a tentative return
+ // value. dictionaryCharCount tells us how many dictionary characters
+ // we passed over on our way to the tentative return value
+ int startPos = text.getIndex();
+ dictionaryCharCount = 0;
+ int result = super.handleNext();
+
+ // if we passed over more than one dictionary character, then we use
+ // divideUpDictionaryRange() to regenerate the cached break positions
+ // for the new range
+ if (dictionaryCharCount > 1 && result - startPos > 1) {
+ divideUpDictionaryRange(startPos, result);
+ }
+
+ // otherwise, the value we got back from the inherited fuction
+ // is our return value, and we can dump the cache
+ else {
+ cachedBreakPositions = null;
+ return result;
+ }
+ }
+
+ // if the cache of break positions has been regenerated (or existed all
+ // along), then just advance to the next break position in the cache
+ // and return it
+ if (cachedBreakPositions != null) {
+ ++positionInCache;
+ text.setIndex(cachedBreakPositions[positionInCache]);
+ return cachedBreakPositions[positionInCache];
+ }
+ return -9999; // SHOULD NEVER GET HERE!
+ }
+
+ /**
+ * Looks up a character category for a character.
+ */
+ @Override
+ protected int lookupCategory(int c) {
+ // this override of lookupCategory() exists only to keep track of whether we've
+ // passed over any dictionary characters. It calls the inherited lookupCategory()
+ // to do the real work, and then checks whether its return value is one of the
+ // categories represented in the dictionary. If it is, bump the dictionary-
+ // character count.
+ int result = super.lookupCategory(c);
+ if (result != RuleBasedBreakIterator.IGNORE && categoryFlags[result]) {
+ ++dictionaryCharCount;
+ }
+ return result;
+ }
+
+ /**
+ * This is the function that actually implements the dictionary-based
+ * algorithm. Given the endpoints of a range of text, it uses the
+ * dictionary to determine the positions of any boundaries in this
+ * range. It stores all the boundary positions it discovers in
+ * cachedBreakPositions so that we only have to do this work once
+ * for each time we enter the range.
+ */
+ @SuppressWarnings("unchecked")
+ private void divideUpDictionaryRange(int startPos, int endPos) {
+ CharacterIterator text = getText();
+
+ // the range we're dividing may begin or end with non-dictionary characters
+ // (i.e., for line breaking, we may have leading or trailing punctuation
+ // that needs to be kept with the word). Seek from the beginning of the
+ // range to the first dictionary character
+ text.setIndex(startPos);
+ int c = getCurrent();
+ int category = lookupCategory(c);
+ while (category == IGNORE || !categoryFlags[category]) {
+ c = getNext();
+ category = lookupCategory(c);
+ }
+
+ // initialize. We maintain two stacks: currentBreakPositions contains
+ // the list of break positions that will be returned if we successfully
+ // finish traversing the whole range now. possibleBreakPositions lists
+ // all other possible word ends we've passed along the way. (Whenever
+ // we reach an error [a sequence of characters that can't begin any word
+ // in the dictionary], we back up, possibly delete some breaks from
+ // currentBreakPositions, move a break from possibleBreakPositions
+ // to currentBreakPositions, and start over from there. This process
+ // continues in this way until we either successfully make it all the way
+ // across the range, or exhaust all of our combinations of break
+ // positions.)
+ Stack currentBreakPositions = new Stack<>();
+ Stack possibleBreakPositions = new Stack<>();
+ List wrongBreakPositions = new ArrayList<>();
+
+ // the dictionary is implemented as a trie, which is treated as a state
+ // machine. -1 represents the end of a legal word. Every word in the
+ // dictionary is represented by a path from the root node to -1. A path
+ // that ends in state 0 is an illegal combination of characters.
+ int state = 0;
+
+ // these two variables are used for error handling. We keep track of the
+ // farthest we've gotten through the range being divided, and the combination
+ // of breaks that got us that far. If we use up all possible break
+ // combinations, the text contains an error or a word that's not in the
+ // dictionary. In this case, we "bless" the break positions that got us the
+ // farthest as real break positions, and then start over from scratch with
+ // the character where the error occurred.
+ int farthestEndPoint = text.getIndex();
+ Stack bestBreakPositions = null;
+
+ // initialize (we always exit the loop with a break statement)
+ c = getCurrent();
+ while (true) {
+
+ // if we can transition to state "-1" from our current state, we're
+ // on the last character of a legal word. Push that position onto
+ // the possible-break-positions stack
+ if (dictionary.getNextState(state, 0) == -1) {
+ possibleBreakPositions.push(text.getIndex());
+ }
+
+ // look up the new state to transition to in the dictionary
+ state = dictionary.getNextStateFromCharacter(state, c);
+
+ // if the character we're sitting on causes us to transition to
+ // the "end of word" state, then it was a non-dictionary character
+ // and we've successfully traversed the whole range. Drop out
+ // of the loop.
+ if (state == -1) {
+ currentBreakPositions.push(text.getIndex());
+ break;
+ }
+
+ // if the character we're sitting on causes us to transition to
+ // the error state, or if we've gone off the end of the range
+ // without transitioning to the "end of word" state, we've hit
+ // an error...
+ else if (state == 0 || text.getIndex() >= endPos) {
+
+ // if this is the farthest we've gotten, take note of it in
+ // case there's an error in the text
+ if (text.getIndex() > farthestEndPoint) {
+ farthestEndPoint = text.getIndex();
+
+ @SuppressWarnings("unchecked")
+ Stack currentBreakPositionsCopy = (Stack) currentBreakPositions.clone();
+
+ bestBreakPositions = currentBreakPositionsCopy;
+ }
+
+ // wrongBreakPositions is a list of all break positions
+ // we've tried starting that didn't allow us to traverse
+ // all the way through the text. Every time we pop a
+ // break position off of currentBreakPositions, we put it
+ // into wrongBreakPositions to avoid trying it again later.
+ // If we make it to this spot, we're either going to back
+ // up to a break in possibleBreakPositions and try starting
+ // over from there, or we've exhausted all possible break
+ // positions and are going to do the fallback procedure.
+ // This loop prevents us from messing with anything in
+ // possibleBreakPositions that didn't work as a starting
+ // point the last time we tried it (this is to prevent a bunch of
+ // repetitive checks from slowing down some extreme cases)
+ while (!possibleBreakPositions.isEmpty()
+ && wrongBreakPositions.contains(possibleBreakPositions.peek())) {
+ possibleBreakPositions.pop();
+ }
+
+ // if we've used up all possible break-position combinations, there's
+ // an error or an unknown word in the text. In this case, we start
+ // over, treating the farthest character we've reached as the beginning
+ // of the range, and "blessing" the break positions that got us that
+ // far as real break positions
+ if (possibleBreakPositions.isEmpty()) {
+ if (bestBreakPositions != null) {
+ currentBreakPositions = bestBreakPositions;
+ if (farthestEndPoint < endPos) {
+ text.setIndex(farthestEndPoint + 1);
+ }
+ else {
+ break;
+ }
+ }
+ else {
+ if ((currentBreakPositions.size() == 0 ||
+ currentBreakPositions.peek().intValue() != text.getIndex())
+ && text.getIndex() != startPos) {
+ currentBreakPositions.push(text.getIndex());
+ }
+ getNext();
+ currentBreakPositions.push(text.getIndex());
+ }
+ }
+
+ // if we still have more break positions we can try, then promote the
+ // last break in possibleBreakPositions into currentBreakPositions,
+ // and get rid of all entries in currentBreakPositions that come after
+ // it. Then back up to that position and start over from there (i.e.,
+ // treat that position as the beginning of a new word)
+ else {
+ Integer temp = possibleBreakPositions.pop();
+ Integer temp2 = null;
+ while (!currentBreakPositions.isEmpty() && temp.intValue() <
+ currentBreakPositions.peek().intValue()) {
+ temp2 = currentBreakPositions.pop();
+ wrongBreakPositions.add(temp2);
+ }
+ currentBreakPositions.push(temp);
+ text.setIndex(currentBreakPositions.peek().intValue());
+ }
+
+ // re-sync "c" for the next go-round, and drop out of the loop if
+ // we've made it off the end of the range
+ c = getCurrent();
+ if (text.getIndex() >= endPos) {
+ break;
+ }
+ }
+
+ // if we didn't hit any exceptional conditions on this last iteration,
+ // just advance to the next character and loop
+ else {
+ c = getNext();
+ }
+ }
+
+ // dump the last break position in the list, and replace it with the actual
+ // end of the range (which may be the same character, or may be further on
+ // because the range actually ended with non-dictionary characters we want to
+ // keep with the word)
+ if (!currentBreakPositions.isEmpty()) {
+ currentBreakPositions.pop();
+ }
+ currentBreakPositions.push(endPos);
+
+ // create a regular array to hold the break positions and copy
+ // the break positions from the stack to the array (in addition,
+ // our starting position goes into this array as a break position).
+ // This array becomes the cache of break positions used by next()
+ // and previous(), so this is where we actually refresh the cache.
+ cachedBreakPositions = new int[currentBreakPositions.size() + 1];
+ cachedBreakPositions[0] = startPos;
+
+ for (int i = 0; i < currentBreakPositions.size(); i++) {
+ cachedBreakPositions[i + 1] = currentBreakPositions.elementAt(i).intValue();
+ }
+ positionInCache = 0;
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,1144 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+
+package sun.text;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.MissingResourceException;
+import sun.text.CompactByteArray;
+import sun.text.SupplementaryCharacterData;
+
+/**
+ * A subclass of BreakIterator whose behavior is specified using a list of rules.
+ *
+ * There are two kinds of rules, which are separated by semicolons: substitutions
+ * and regular expressions.
+ *
+ * A substitution rule defines a name that can be used in place of an expression. It
+ * consists of a name, which is a string of characters contained in angle brackets, an equals
+ * sign, and an expression. (There can be no whitespace on either side of the equals sign.)
+ * To keep its syntactic meaning intact, the expression must be enclosed in parentheses or
+ * square brackets. A substitution is visible after its definition, and is filled in using
+ * simple textual substitution. Substitution definitions can contain other substitutions, as
+ * long as those substitutions have been defined first. Substitutions are generally used to
+ * make the regular expressions (which can get quite complex) shorted and easier to read.
+ * They typically define either character categories or commonly-used subexpressions.
+ *
+ * There is one special substitution. If the description defines a substitution
+ * called "<ignore>", the expression must be a [] expression, and the
+ * expression defines a set of characters (the "ignore characters") that
+ * will be transparent to the BreakIterator. A sequence of characters will break the
+ * same way it would if any ignore characters it contains are taken out. Break
+ * positions never occur befoer ignore characters.
+ *
+ * A regular expression uses a subset of the normal Unix regular-expression syntax, and
+ * defines a sequence of characters to be kept together. With one significant exception, the
+ * iterator uses a longest-possible-match algorithm when matching text to regular
+ * expressions. The iterator also treats descriptions containing multiple regular expressions
+ * as if they were ORed together (i.e., as if they were separated by |).
+ *
+ * The special characters recognized by the regular-expression parser are as follows:
+ *
+ *
+ *
+ *
+ * * |
+ * Specifies that the expression preceding the asterisk may occur any number
+ * of times (including not at all). |
+ *
+ *
+ * {} |
+ * Encloses a sequence of characters that is optional. |
+ *
+ *
+ * () |
+ * Encloses a sequence of characters. If followed by *, the sequence
+ * repeats. Otherwise, the parentheses are just a grouping device and a way to delimit
+ * the ends of expressions containing |. |
+ *
+ *
+ * | |
+ * Separates two alternative sequences of characters. Either one
+ * sequence or the other, but not both, matches this expression. The | character can
+ * only occur inside (). |
+ *
+ *
+ * . |
+ * Matches any character. |
+ *
+ *
+ * *? |
+ * Specifies a non-greedy asterisk. *? works the same way as *, except
+ * when there is overlap between the last group of characters in the expression preceding the
+ * * and the first group of characters following the *. When there is this kind of
+ * overlap, * will match the longest sequence of characters that match the expression before
+ * the *, and *? will match the shortest sequence of characters matching the expression
+ * before the *?. For example, if you have "xxyxyyyxyxyxxyxyxyy" in the text,
+ * "x[xy]*x" will match through to the last x (i.e., "xxyxyyyxyxyxxyxyxyy",
+ * but "x[xy]*?x" will only match the first two xes ("xxyxyyyxyxyxxyxyxyy"). |
+ *
+ *
+ * [] |
+ * Specifies a group of alternative characters. A [] expression will
+ * match any single character that is specified in the [] expression. For more on the
+ * syntax of [] expressions, see below. |
+ *
+ *
+ * / |
+ * Specifies where the break position should go if text matches this
+ * expression. (e.g., "[a-z]*/[:Zs:]*[1-0]" will match if the iterator sees a run
+ * of letters, followed by a run of whitespace, followed by a digit, but the break position
+ * will actually go before the whitespace). Expressions that don't contain / put the
+ * break position at the end of the matching text. |
+ *
+ *
+ * \ |
+ * Escape character. The \ itself is ignored, but causes the next
+ * character to be treated as literal character. This has no effect for many
+ * characters, but for the characters listed above, this deprives them of their special
+ * meaning. (There are no special escape sequences for Unicode characters, or tabs and
+ * newlines; these are all handled by a higher-level protocol. In a Java string,
+ * "\n" will be converted to a literal newline character by the time the
+ * regular-expression parser sees it. Of course, this means that \ sequences that are
+ * visible to the regexp parser must be written as \\ when inside a Java string.) All
+ * characters in the ASCII range except for letters, digits, and control characters are
+ * reserved characters to the parser and must be preceded by \ even if they currently don't
+ * mean anything. |
+ *
+ *
+ * ! |
+ * If ! appears at the beginning of a regular expression, it tells the regexp
+ * parser that this expression specifies the backwards-iteration behavior of the iterator,
+ * and not its normal iteration behavior. This is generally only used in situations
+ * where the automatically-generated backwards-iteration brhavior doesn't produce
+ * satisfactory results and must be supplemented with extra client-specified rules. |
+ *
+ *
+ * (all others) |
+ * All other characters are treated as literal characters, which must match
+ * the corresponding character(s) in the text exactly. |
+ *
+ *
+ *
+ *
+ * Within a [] expression, a number of other special characters can be used to specify
+ * groups of characters:
+ *
+ *
+ *
+ *
+ * - |
+ * Specifies a range of matching characters. For example
+ * "[a-p]" matches all lowercase Latin letters from a to p (inclusive). The -
+ * sign specifies ranges of continuous Unicode numeric values, not ranges of characters in a
+ * language's alphabetical order: "[a-z]" doesn't include capital letters, nor does
+ * it include accented letters such as a-umlaut. |
+ *
+ *
+ * :: |
+ * A pair of colons containing a one- or two-letter code matches all
+ * characters in the corresponding Unicode category. The two-letter codes are the same
+ * as the two-letter codes in the Unicode database (for example, "[:Sc::Sm:]"
+ * matches all currency symbols and all math symbols). Specifying a one-letter code is
+ * the same as specifying all two-letter codes that begin with that letter (for example,
+ * "[:L:]" matches all letters, and is equivalent to
+ * "[:Lu::Ll::Lo::Lm::Lt:]"). Anything other than a valid two-letter Unicode
+ * category code or a single letter that begins a Unicode category code is illegal within
+ * colons. |
+ *
+ *
+ * [] |
+ * [] expressions can nest. This has no effect, except when used in
+ * conjunction with the ^ token. |
+ *
+ *
+ * ^ |
+ * Excludes the character (or the characters in the [] expression) following
+ * it from the group of characters. For example, "[a-z^p]" matches all Latin
+ * lowercase letters except p. "[:L:^[\u4e00-\u9fff]]" matches all letters
+ * except the Han ideographs. |
+ *
+ *
+ * (all others) |
+ * All other characters are treated as literal characters. (For
+ * example, "[aeiou]" specifies just the letters a, e, i, o, and u.) |
+ *
+ *
+ *
+ *
+ * For a more complete explanation, see http://www.ibm.com/java/education/boundaries/boundaries.html.
+ * For examples, see the resource data (which is annotated).
+ *
+ * @author Richard Gillam
+ */
+public class RuleBasedBreakIterator extends BreakIterator {
+
+ /**
+ * A token used as a character-category value to identify ignore characters
+ */
+ protected static final byte IGNORE = -1;
+
+ /**
+ * The state number of the starting state
+ */
+ private static final short START_STATE = 1;
+
+ /**
+ * The state-transition value indicating "stop"
+ */
+ private static final short STOP_STATE = 0;
+
+ /**
+ * Magic number for the BreakIterator data file format.
+ */
+ static final byte[] LABEL = {
+ (byte)'B', (byte)'I', (byte)'d', (byte)'a', (byte)'t', (byte)'a',
+ (byte)'\0'
+ };
+ static final int LABEL_LENGTH = LABEL.length;
+
+ /**
+ * Version number of the dictionary that was read in.
+ */
+ static final byte supportedVersion = 1;
+
+ /**
+ * An array length of indices for BMP characters
+ */
+ private static final int BMP_INDICES_LENGTH = 512;
+
+ /**
+ * Tables that indexes from character values to character category numbers
+ */
+ private CompactByteArray charCategoryTable = null;
+ private SupplementaryCharacterData supplementaryCharCategoryTable = null;
+
+ /**
+ * The table of state transitions used for forward iteration
+ */
+ private short[] stateTable = null;
+
+ /**
+ * The table of state transitions used to sync up the iterator with the
+ * text in backwards and random-access iteration
+ */
+ private short[] backwardsStateTable = null;
+
+ /**
+ * A list of flags indicating which states in the state table are accepting
+ * ("end") states
+ */
+ private boolean[] endStates = null;
+
+ /**
+ * A list of flags indicating which states in the state table are
+ * lookahead states (states which turn lookahead on and off)
+ */
+ private boolean[] lookaheadStates = null;
+
+ /**
+ * A table for additional data. May be used by a subclass of
+ * RuleBasedBreakIterator.
+ */
+ private byte[] additionalData = null;
+
+ /**
+ * The number of character categories (and, thus, the number of columns in
+ * the state tables)
+ */
+ private int numCategories;
+
+ /**
+ * The character iterator through which this BreakIterator accesses the text
+ */
+ private CharacterIterator text = null;
+
+ /**
+ * A CRC32 value of all data in datafile
+ */
+ private long checksum;
+
+ //=======================================================================
+ // constructors
+ //=======================================================================
+
+ /**
+ * Constructs a RuleBasedBreakIterator using the given rule data.
+ *
+ * @throws MissingResourceException if the rule data is invalid or corrupted
+ */
+ public RuleBasedBreakIterator(String ruleFile, byte[] ruleData) {
+ ByteBuffer bb = ByteBuffer.wrap(ruleData);
+ try {
+ validateRuleData(ruleFile, bb);
+ setupTables(ruleFile, bb);
+ } catch (BufferUnderflowException bue) {
+ MissingResourceException e;
+ e = new MissingResourceException("Corrupted rule data file", ruleFile, "");
+ e.initCause(bue);
+ throw e;
+ }
+ }
+
+ /**
+ * Initializes the fields with the given rule data.
+ * The data format is as follows:
+ *
+ * BreakIteratorData {
+ * u1 magic[7];
+ * u1 version;
+ * u4 totalDataSize;
+ * header_info header;
+ * body value;
+ * }
+ *
+ * totalDataSize
is the summation of the size of
+ * header_info
and body
in byte count.
+ *
+ * In header
, each field except for checksum implies the
+ * length of each field. Since BMPdataLength
is a fixed-length
+ * data(512 entries), its length isn't included in header
.
+ * checksum
is a CRC32 value of all in body
.
+ *
+ * header_info {
+ * u4 stateTableLength;
+ * u4 backwardsStateTableLength;
+ * u4 endStatesLength;
+ * u4 lookaheadStatesLength;
+ * u4 BMPdataLength;
+ * u4 nonBMPdataLength;
+ * u4 additionalDataLength;
+ * u8 checksum;
+ * }
+ *
+ *
+ *
+ * Finally, BMPindices
and BMPdata
are set to
+ * charCategoryTable
. nonBMPdata
is set to
+ * supplementaryCharCategoryTable
.
+ *
+ * body {
+ * u2 stateTable[stateTableLength];
+ * u2 backwardsStateTable[backwardsStateTableLength];
+ * u1 endStates[endStatesLength];
+ * u1 lookaheadStates[lookaheadStatesLength];
+ * u2 BMPindices[512];
+ * u1 BMPdata[BMPdataLength];
+ * u4 nonBMPdata[numNonBMPdataLength];
+ * u1 additionalData[additionalDataLength];
+ * }
+ *
+ *
+ * @throws BufferUnderflowException if the end-of-data is reached before
+ * setting up all the tables
+ */
+ private void setupTables(String ruleFile, ByteBuffer bb) {
+ /* Read header_info. */
+ int stateTableLength = bb.getInt();
+ int backwardsStateTableLength = bb.getInt();
+ int endStatesLength = bb.getInt();
+ int lookaheadStatesLength = bb.getInt();
+ int BMPdataLength = bb.getInt();
+ int nonBMPdataLength = bb.getInt();
+ int additionalDataLength = bb.getInt();
+ checksum = bb.getLong();
+
+ /* Read stateTable[numCategories * numRows] */
+ stateTable = new short[stateTableLength];
+ for (int i = 0; i < stateTableLength; i++) {
+ stateTable[i] = bb.getShort();
+ }
+
+ /* Read backwardsStateTable[numCategories * numRows] */
+ backwardsStateTable = new short[backwardsStateTableLength];
+ for (int i = 0; i < backwardsStateTableLength; i++) {
+ backwardsStateTable[i] = bb.getShort();
+ }
+
+ /* Read endStates[numRows] */
+ endStates = new boolean[endStatesLength];
+ for (int i = 0; i < endStatesLength; i++) {
+ endStates[i] = bb.get() == 1;
+ }
+
+ /* Read lookaheadStates[numRows] */
+ lookaheadStates = new boolean[lookaheadStatesLength];
+ for (int i = 0; i < lookaheadStatesLength; i++) {
+ lookaheadStates[i] = bb.get() == 1;
+ }
+
+ /* Read a category table and indices for BMP characters. */
+ short[] temp1 = new short[BMP_INDICES_LENGTH]; // BMPindices
+ for (int i = 0; i < BMP_INDICES_LENGTH; i++) {
+ temp1[i] = bb.getShort();
+ }
+ byte[] temp2 = new byte[BMPdataLength]; // BMPdata
+ bb.get(temp2);
+ charCategoryTable = new CompactByteArray(temp1, temp2);
+
+ /* Read a category table for non-BMP characters. */
+ int[] temp3 = new int[nonBMPdataLength];
+ for (int i = 0; i < nonBMPdataLength; i++) {
+ temp3[i] = bb.getInt();
+ }
+ supplementaryCharCategoryTable = new SupplementaryCharacterData(temp3);
+
+ /* Read additional data */
+ if (additionalDataLength > 0) {
+ additionalData = new byte[additionalDataLength];
+ bb.get(additionalData);
+ }
+ assert bb.position() == bb.limit();
+
+ /* Set numCategories */
+ numCategories = stateTable.length / endStates.length;
+ }
+
+ /**
+ * Validates the magic number, version, and the length of the given data.
+ *
+ * @throws BufferUnderflowException if the end-of-data is reached while
+ * validating data
+ * @throws MissingResourceException if valification failed
+ */
+ void validateRuleData(String ruleFile, ByteBuffer bb) {
+ /* Verify the magic number. */
+ for (int i = 0; i < LABEL_LENGTH; i++) {
+ if (bb.get() != LABEL[i]) {
+ throw new MissingResourceException("Wrong magic number",
+ ruleFile, "");
+ }
+ }
+
+ /* Verify the version number. */
+ byte version = bb.get();
+ if (version != supportedVersion) {
+ throw new MissingResourceException("Unsupported version(" + version + ")",
+ ruleFile, "");
+ }
+
+ // Check the length of the rest of data
+ int len = bb.getInt();
+ if (bb.position() + len != bb.limit()) {
+ throw new MissingResourceException("Wrong data length",
+ ruleFile, "");
+ }
+ }
+
+ byte[] getAdditionalData() {
+ return additionalData;
+ }
+
+ void setAdditionalData(byte[] b) {
+ additionalData = b;
+ }
+
+ //=======================================================================
+ // boilerplate
+ //=======================================================================
+ /**
+ * Clones this iterator.
+ * @return A newly-constructed RuleBasedBreakIterator with the same
+ * behavior as this one.
+ */
+ @Override
+ public Object clone() {
+ RuleBasedBreakIterator result = (RuleBasedBreakIterator) super.clone();
+ if (text != null) {
+ result.text = (CharacterIterator) text.clone();
+ }
+ return result;
+ }
+
+ /**
+ * Returns true if both BreakIterators are of the same class, have the same
+ * rules, and iterate over the same text.
+ */
+ @Override
+ public boolean equals(Object that) {
+ try {
+ if (that == null) {
+ return false;
+ }
+
+ RuleBasedBreakIterator other = (RuleBasedBreakIterator) that;
+ if (checksum != other.checksum) {
+ return false;
+ }
+ if (text == null) {
+ return other.text == null;
+ } else {
+ return text.equals(other.text);
+ }
+ }
+ catch(ClassCastException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns text
+ */
+ @Override
+ public String toString() {
+ return "[checksum=0x" + Long.toHexString(checksum) + ']';
+ }
+
+ /**
+ * Compute a hashcode for this BreakIterator
+ * @return A hash code
+ */
+ @Override
+ public int hashCode() {
+ return (int)checksum;
+ }
+
+ //=======================================================================
+ // BreakIterator overrides
+ //=======================================================================
+
+ /**
+ * Sets the current iteration position to the beginning of the text.
+ * (i.e., the CharacterIterator's starting offset).
+ * @return The offset of the beginning of the text.
+ */
+ @Override
+ public int first() {
+ CharacterIterator t = getText();
+
+ t.first();
+ return t.getIndex();
+ }
+
+ /**
+ * Sets the current iteration position to the end of the text.
+ * (i.e., the CharacterIterator's ending offset).
+ * @return The text's past-the-end offset.
+ */
+ @Override
+ public int last() {
+ CharacterIterator t = getText();
+
+ // I'm not sure why, but t.last() returns the offset of the last character,
+ // rather than the past-the-end offset
+ t.setIndex(t.getEndIndex());
+ return t.getIndex();
+ }
+
+ /**
+ * Advances the iterator either forward or backward the specified number of steps.
+ * Negative values move backward, and positive values move forward. This is
+ * equivalent to repeatedly calling next() or previous().
+ * @param n The number of steps to move. The sign indicates the direction
+ * (negative is backwards, and positive is forwards).
+ * @return The character offset of the boundary position n boundaries away from
+ * the current one.
+ */
+ @Override
+ public int next(int n) {
+ int result = current();
+ while (n > 0) {
+ result = handleNext();
+ --n;
+ }
+ while (n < 0) {
+ result = previous();
+ ++n;
+ }
+ return result;
+ }
+
+ /**
+ * Advances the iterator to the next boundary position.
+ * @return The position of the first boundary after this one.
+ */
+ @Override
+ public int next() {
+ return handleNext();
+ }
+
+ private int cachedLastKnownBreak = BreakIterator.DONE;
+
+ /**
+ * Advances the iterator backwards, to the last boundary preceding this one.
+ * @return The position of the last boundary position preceding this one.
+ */
+ @Override
+ public int previous() {
+ // if we're already sitting at the beginning of the text, return DONE
+ CharacterIterator text = getText();
+ if (current() == text.getBeginIndex()) {
+ return BreakIterator.DONE;
+ }
+
+ // set things up. handlePrevious() will back us up to some valid
+ // break position before the current position (we back our internal
+ // iterator up one step to prevent handlePrevious() from returning
+ // the current position), but not necessarily the last one before
+ // where we started
+ int start = current();
+ int lastResult = cachedLastKnownBreak;
+ if (lastResult >= start || lastResult <= BreakIterator.DONE) {
+ getPrevious();
+ lastResult = handlePrevious();
+ } else {
+ //it might be better to check if handlePrevious() give us closer
+ //safe value but handlePrevious() is slow too
+ //So, this has to be done carefully
+ text.setIndex(lastResult);
+ }
+ int result = lastResult;
+
+ // iterate forward from the known break position until we pass our
+ // starting point. The last break position before the starting
+ // point is our return value
+ while (result != BreakIterator.DONE && result < start) {
+ lastResult = result;
+ result = handleNext();
+ }
+
+ // set the current iteration position to be the last break position
+ // before where we started, and then return that value
+ text.setIndex(lastResult);
+ cachedLastKnownBreak = lastResult;
+ return lastResult;
+ }
+
+ /**
+ * Returns previous character
+ */
+ private int getPrevious() {
+ char c2 = text.previous();
+ if (Character.isLowSurrogate(c2) &&
+ text.getIndex() > text.getBeginIndex()) {
+ char c1 = text.previous();
+ if (Character.isHighSurrogate(c1)) {
+ return Character.toCodePoint(c1, c2);
+ } else {
+ text.next();
+ }
+ }
+ return (int)c2;
+ }
+
+ /**
+ * Returns current character
+ */
+ int getCurrent() {
+ char c1 = text.current();
+ if (Character.isHighSurrogate(c1) &&
+ text.getIndex() < text.getEndIndex()) {
+ char c2 = text.next();
+ text.previous();
+ if (Character.isLowSurrogate(c2)) {
+ return Character.toCodePoint(c1, c2);
+ }
+ }
+ return (int)c1;
+ }
+
+ /**
+ * Returns the count of next character.
+ */
+ private int getCurrentCodePointCount() {
+ char c1 = text.current();
+ if (Character.isHighSurrogate(c1) &&
+ text.getIndex() < text.getEndIndex()) {
+ char c2 = text.next();
+ text.previous();
+ if (Character.isLowSurrogate(c2)) {
+ return 2;
+ }
+ }
+ return 1;
+ }
+
+ /**
+ * Returns next character
+ */
+ int getNext() {
+ int index = text.getIndex();
+ int endIndex = text.getEndIndex();
+ if (index == endIndex ||
+ (index += getCurrentCodePointCount()) >= endIndex) {
+ return CharacterIterator.DONE;
+ }
+ text.setIndex(index);
+ return getCurrent();
+ }
+
+ /**
+ * Returns the position of next character.
+ */
+ private int getNextIndex() {
+ int index = text.getIndex() + getCurrentCodePointCount();
+ int endIndex = text.getEndIndex();
+ if (index > endIndex) {
+ return endIndex;
+ } else {
+ return index;
+ }
+ }
+
+ /**
+ * Throw IllegalArgumentException unless begin <= offset < end.
+ */
+ protected static final void checkOffset(int offset, CharacterIterator text) {
+ if (offset < text.getBeginIndex() || offset > text.getEndIndex()) {
+ throw new IllegalArgumentException("offset out of bounds");
+ }
+ }
+
+ /**
+ * Sets the iterator to refer to the first boundary position following
+ * the specified position.
+ * @offset The position from which to begin searching for a break position.
+ * @return The position of the first break after the current position.
+ */
+ @Override
+ public int following(int offset) {
+
+ CharacterIterator text = getText();
+ checkOffset(offset, text);
+
+ // Set our internal iteration position (temporarily)
+ // to the position passed in. If this is the _beginning_ position,
+ // then we can just use next() to get our return value
+ text.setIndex(offset);
+ if (offset == text.getBeginIndex()) {
+ cachedLastKnownBreak = handleNext();
+ return cachedLastKnownBreak;
+ }
+
+ // otherwise, we have to sync up first. Use handlePrevious() to back
+ // us up to a known break position before the specified position (if
+ // we can determine that the specified position is a break position,
+ // we don't back up at all). This may or may not be the last break
+ // position at or before our starting position. Advance forward
+ // from here until we've passed the starting position. The position
+ // we stop on will be the first break position after the specified one.
+ int result = cachedLastKnownBreak;
+ if (result >= offset || result <= BreakIterator.DONE) {
+ result = handlePrevious();
+ } else {
+ //it might be better to check if handlePrevious() give us closer
+ //safe value but handlePrevious() is slow too
+ //So, this has to be done carefully
+ text.setIndex(result);
+ }
+ while (result != BreakIterator.DONE && result <= offset) {
+ result = handleNext();
+ }
+ cachedLastKnownBreak = result;
+ return result;
+ }
+
+ /**
+ * Sets the iterator to refer to the last boundary position before the
+ * specified position.
+ * @offset The position to begin searching for a break from.
+ * @return The position of the last boundary before the starting position.
+ */
+ @Override
+ public int preceding(int offset) {
+ // if we start by updating the current iteration position to the
+ // position specified by the caller, we can just use previous()
+ // to carry out this operation
+ CharacterIterator text = getText();
+ checkOffset(offset, text);
+ text.setIndex(offset);
+ return previous();
+ }
+
+ /**
+ * Returns true if the specified position is a boundary position. As a side
+ * effect, leaves the iterator pointing to the first boundary position at
+ * or after "offset".
+ * @param offset the offset to check.
+ * @return True if "offset" is a boundary position.
+ */
+ @Override
+ public boolean isBoundary(int offset) {
+ CharacterIterator text = getText();
+ checkOffset(offset, text);
+ if (offset == text.getBeginIndex()) {
+ return true;
+ }
+
+ // to check whether this is a boundary, we can use following() on the
+ // position before the specified one and return true if the position we
+ // get back is the one the user specified
+ else {
+ return following(offset - 1) == offset;
+ }
+ }
+
+ /**
+ * Returns the current iteration position.
+ * @return The current iteration position.
+ */
+ @Override
+ public int current() {
+ return getText().getIndex();
+ }
+
+ /**
+ * Return a CharacterIterator over the text being analyzed. This version
+ * of this method returns the actual CharacterIterator we're using internally.
+ * Changing the state of this iterator can have undefined consequences. If
+ * you need to change it, clone it first.
+ * @return An iterator over the text being analyzed.
+ */
+ @Override
+ public CharacterIterator getText() {
+ // The iterator is initialized pointing to no text at all, so if this
+ // function is called while we're in that state, we have to fudge an
+ // iterator to return.
+ if (text == null) {
+ text = new StringCharacterIterator("");
+ }
+ return text;
+ }
+
+ /**
+ * Set the iterator to analyze a new piece of text. This function resets
+ * the current iteration position to the beginning of the text.
+ * @param newText An iterator over the text to analyze.
+ */
+ @Override
+ public void setText(CharacterIterator newText) {
+ // Test iterator to see if we need to wrap it in a SafeCharIterator.
+ // The correct behavior for CharacterIterators is to allow the
+ // position to be set to the endpoint of the iterator. Many
+ // CharacterIterators do not uphold this, so this is a workaround
+ // to permit them to use this class.
+ int end = newText.getEndIndex();
+ boolean goodIterator;
+ try {
+ newText.setIndex(end); // some buggy iterators throw an exception here
+ goodIterator = newText.getIndex() == end;
+ }
+ catch(IllegalArgumentException e) {
+ goodIterator = false;
+ }
+
+ if (goodIterator) {
+ text = newText;
+ }
+ else {
+ text = new SafeCharIterator(newText);
+ }
+ text.first();
+
+ cachedLastKnownBreak = BreakIterator.DONE;
+ }
+
+
+ //=======================================================================
+ // implementation
+ //=======================================================================
+
+ /**
+ * This method is the actual implementation of the next() method. All iteration
+ * vectors through here. This method initializes the state machine to state 1
+ * and advances through the text character by character until we reach the end
+ * of the text or the state machine transitions to state 0. We update our return
+ * value every time the state machine passes through a possible end state.
+ */
+ protected int handleNext() {
+ // if we're already at the end of the text, return DONE.
+ CharacterIterator text = getText();
+ if (text.getIndex() == text.getEndIndex()) {
+ return BreakIterator.DONE;
+ }
+
+ // no matter what, we always advance at least one character forward
+ int result = getNextIndex();
+ int lookaheadResult = 0;
+
+ // begin in state 1
+ int state = START_STATE;
+ int category;
+ int c = getCurrent();
+
+ // loop until we reach the end of the text or transition to state 0
+ while (c != CharacterIterator.DONE && state != STOP_STATE) {
+
+ // look up the current character's character category (which tells us
+ // which column in the state table to look at)
+ category = lookupCategory(c);
+
+ // if the character isn't an ignore character, look up a state
+ // transition in the state table
+ if (category != IGNORE) {
+ state = lookupState(state, category);
+ }
+
+ // if the state we've just transitioned to is a lookahead state,
+ // (but not also an end state), save its position. If it's
+ // both a lookahead state and an end state, update the break position
+ // to the last saved lookup-state position
+ if (lookaheadStates[state]) {
+ if (endStates[state]) {
+ result = lookaheadResult;
+ }
+ else {
+ lookaheadResult = getNextIndex();
+ }
+ }
+
+ // otherwise, if the state we've just transitioned to is an accepting
+ // state, update the break position to be the current iteration position
+ else {
+ if (endStates[state]) {
+ result = getNextIndex();
+ }
+ }
+
+ c = getNext();
+ }
+
+ // if we've run off the end of the text, and the very last character took us into
+ // a lookahead state, advance the break position to the lookahead position
+ // (the theory here is that if there are no characters at all after the lookahead
+ // position, that always matches the lookahead criteria)
+ if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) {
+ result = lookaheadResult;
+ }
+
+ text.setIndex(result);
+ return result;
+ }
+
+ /**
+ * This method backs the iterator back up to a "safe position" in the text.
+ * This is a position that we know, without any context, must be a break position.
+ * The various calling methods then iterate forward from this safe position to
+ * the appropriate position to return. (For more information, see the description
+ * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
+ */
+ protected int handlePrevious() {
+ CharacterIterator text = getText();
+ int state = START_STATE;
+ int category = 0;
+ int lastCategory = 0;
+ int c = getCurrent();
+
+ // loop until we reach the beginning of the text or transition to state 0
+ while (c != CharacterIterator.DONE && state != STOP_STATE) {
+
+ // save the last character's category and look up the current
+ // character's category
+ lastCategory = category;
+ category = lookupCategory(c);
+
+ // if the current character isn't an ignore character, look up a
+ // state transition in the backwards state table
+ if (category != IGNORE) {
+ state = lookupBackwardState(state, category);
+ }
+
+ // then advance one character backwards
+ c = getPrevious();
+ }
+
+ // if we didn't march off the beginning of the text, we're either one or two
+ // positions away from the real break position. (One because of the call to
+ // previous() at the end of the loop above, and another because the character
+ // that takes us into the stop state will always be the character BEFORE
+ // the break position.)
+ if (c != CharacterIterator.DONE) {
+ if (lastCategory != IGNORE) {
+ getNext();
+ getNext();
+ }
+ else {
+ getNext();
+ }
+ }
+ return text.getIndex();
+ }
+
+ /**
+ * Looks up a character's category (i.e., its category for breaking purposes,
+ * not its Unicode category)
+ */
+ protected int lookupCategory(int c) {
+ if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ return charCategoryTable.elementAt((char)c);
+ } else {
+ return supplementaryCharCategoryTable.getValue(c);
+ }
+ }
+
+ /**
+ * Given a current state and a character category, looks up the
+ * next state to transition to in the state table.
+ */
+ protected int lookupState(int state, int category) {
+ return stateTable[state * numCategories + category];
+ }
+
+ /**
+ * Given a current state and a character category, looks up the
+ * next state to transition to in the backwards state table.
+ */
+ protected int lookupBackwardState(int state, int category) {
+ return backwardsStateTable[state * numCategories + category];
+ }
+
+ /*
+ * This class exists to work around a bug in incorrect implementations
+ * of CharacterIterator, which incorrectly handle setIndex(endIndex).
+ * This iterator relies only on base.setIndex(n) where n is less than
+ * endIndex.
+ *
+ * One caveat: if the base iterator's begin and end indices change
+ * the change will not be reflected by this wrapper. Does that matter?
+ */
+ // TODO: Review this class to see if it's still required.
+ private static final class SafeCharIterator implements CharacterIterator,
+ Cloneable {
+
+ private CharacterIterator base;
+ private int rangeStart;
+ private int rangeLimit;
+ private int currentIndex;
+
+ SafeCharIterator(CharacterIterator base) {
+ this.base = base;
+ this.rangeStart = base.getBeginIndex();
+ this.rangeLimit = base.getEndIndex();
+ this.currentIndex = base.getIndex();
+ }
+
+ @Override
+ public char first() {
+ return setIndex(rangeStart);
+ }
+
+ @Override
+ public char last() {
+ return setIndex(rangeLimit - 1);
+ }
+
+ @Override
+ public char current() {
+ if (currentIndex < rangeStart || currentIndex >= rangeLimit) {
+ return DONE;
+ }
+ else {
+ return base.setIndex(currentIndex);
+ }
+ }
+
+ @Override
+ public char next() {
+
+ currentIndex++;
+ if (currentIndex >= rangeLimit) {
+ currentIndex = rangeLimit;
+ return DONE;
+ }
+ else {
+ return base.setIndex(currentIndex);
+ }
+ }
+
+ @Override
+ public char previous() {
+
+ currentIndex--;
+ if (currentIndex < rangeStart) {
+ currentIndex = rangeStart;
+ return DONE;
+ }
+ else {
+ return base.setIndex(currentIndex);
+ }
+ }
+
+ @Override
+ public char setIndex(int i) {
+
+ if (i < rangeStart || i > rangeLimit) {
+ throw new IllegalArgumentException("Invalid position");
+ }
+ currentIndex = i;
+ return current();
+ }
+
+ @Override
+ public int getBeginIndex() {
+ return rangeStart;
+ }
+
+ @Override
+ public int getEndIndex() {
+ return rangeLimit;
+ }
+
+ @Override
+ public int getIndex() {
+ return currentIndex;
+ }
+
+ @Override
+ public Object clone() {
+
+ SafeCharIterator copy = null;
+ try {
+ copy = (SafeCharIterator) super.clone();
+ }
+ catch(CloneNotSupportedException e) {
+ throw new Error("Clone not supported: " + e);
+ }
+
+ CharacterIterator copyOfBase = (CharacterIterator) base.clone();
+ copy.base = copyOfBase;
+ return copy;
+ }
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/text/resources/BreakIteratorResources.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/resources/BreakIteratorResources.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.text.resources;
+
+import java.util.ResourceBundle;
+import sun.util.resources.BreakIteratorResourceBundle;
+
+public class BreakIteratorResources extends BreakIteratorResourceBundle {
+ @Override
+ protected ResourceBundle getBreakIteratorInfo() {
+ return new BreakIteratorInfo();
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/locale/provider/BreakDictionary.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakDictionary.java Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-package sun.util.locale.provider;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.MissingResourceException;
-import sun.text.CompactByteArray;
-import sun.text.SupplementaryCharacterData;
-
-/**
- * This is the class that represents the list of known words used by
- * DictionaryBasedBreakIterator. The conceptual data structure used
- * here is a trie: there is a node hanging off the root node for every
- * letter that can start a word. Each of these nodes has a node hanging
- * off of it for every letter that can be the second letter of a word
- * if this node is the first letter, and so on. The trie is represented
- * as a two-dimensional array that can be treated as a table of state
- * transitions. Indexes are used to compress this array, taking
- * advantage of the fact that this array will always be very sparse.
- */
-class BreakDictionary {
-
- //=========================================================================
- // data members
- //=========================================================================
-
- /**
- * The version of the dictionary that was read in.
- */
- private static int supportedVersion = 1;
-
- /**
- * Maps from characters to column numbers. The main use of this is to
- * avoid making room in the array for empty columns.
- */
- private CompactByteArray columnMap = null;
- private SupplementaryCharacterData supplementaryCharColumnMap = null;
-
- /**
- * The number of actual columns in the table
- */
- private int numCols;
-
- /**
- * Columns are organized into groups of 32. This says how many
- * column groups. (We could calculate this, but we store the
- * value to avoid having to repeatedly calculate it.)
- */
- private int numColGroups;
-
- /**
- * The actual compressed state table. Each conceptual row represents
- * a state, and the cells in it contain the row numbers of the states
- * to transition to for each possible letter. 0 is used to indicate
- * an illegal combination of letters (i.e., the error state). The
- * table is compressed by eliminating all the unpopulated (i.e., zero)
- * cells. Multiple conceptual rows can then be doubled up in a single
- * physical row by sliding them up and possibly shifting them to one
- * side or the other so the populated cells don't collide. Indexes
- * are used to identify unpopulated cells and to locate populated cells.
- */
- private short[] table = null;
-
- /**
- * This index maps logical row numbers to physical row numbers
- */
- private short[] rowIndex = null;
-
- /**
- * A bitmap is used to tell which cells in the comceptual table are
- * populated. This array contains all the unique bit combinations
- * in that bitmap. If the table is more than 32 columns wide,
- * successive entries in this array are used for a single row.
- */
- private int[] rowIndexFlags = null;
-
- /**
- * This index maps from a logical row number into the bitmap table above.
- * (This keeps us from storing duplicate bitmap combinations.) Since there
- * are a lot of rows with only one populated cell, instead of wasting space
- * in the bitmap table, we just store a negative number in this index for
- * rows with one populated cell. The absolute value of that number is
- * the column number of the populated cell.
- */
- private short[] rowIndexFlagsIndex = null;
-
- /**
- * For each logical row, this index contains a constant that is added to
- * the logical column number to get the physical column number
- */
- private byte[] rowIndexShifts = null;
-
- //=========================================================================
- // deserialization
- //=========================================================================
-
- BreakDictionary(Module module, String dictionaryName)
- throws IOException, MissingResourceException {
-
- readDictionaryFile(module, dictionaryName);
- }
-
- private void readDictionaryFile(final Module module, final String dictionaryName)
- throws IOException, MissingResourceException {
-
- BufferedInputStream in;
- try {
- PrivilegedExceptionAction pa = () -> {
- String pathName = "jdk.localedata".equals(module.getName()) ?
- "sun/text/resources/ext/" :
- "sun/text/resources/";
- InputStream is = module.getResourceAsStream(pathName + dictionaryName);
- if (is == null) {
- // Try to load the file with "java.base" module instance. Assumption
- // here is that the fall back data files to be read should reside in
- // java.base.
- is = BreakDictionary.class.getModule().getResourceAsStream("sun/text/resources/" + dictionaryName);
- }
-
- return new BufferedInputStream(is);
- };
- in = AccessController.doPrivileged(pa);
- }
- catch (PrivilegedActionException e) {
- throw new InternalError(e.toString(), e);
- }
-
- byte[] buf = new byte[8];
- if (in.read(buf) != 8) {
- throw new MissingResourceException("Wrong data length",
- dictionaryName, "");
- }
-
- // check version
- int version = RuleBasedBreakIterator.getInt(buf, 0);
- if (version != supportedVersion) {
- throw new MissingResourceException("Dictionary version(" + version + ") is unsupported",
- dictionaryName, "");
- }
-
- // get data size
- int len = RuleBasedBreakIterator.getInt(buf, 4);
- buf = new byte[len];
- if (in.read(buf) != len) {
- throw new MissingResourceException("Wrong data length",
- dictionaryName, "");
- }
-
- // close the stream
- in.close();
-
- int l;
- int offset = 0;
-
- // read in the column map for BMP characteres (this is serialized in
- // its internal form: an index array followed by a data array)
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- short[] temp = new short[l];
- for (int i = 0; i < l; i++, offset+=2) {
- temp[i] = RuleBasedBreakIterator.getShort(buf, offset);
- }
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- byte[] temp2 = new byte[l];
- for (int i = 0; i < l; i++, offset++) {
- temp2[i] = buf[offset];
- }
- columnMap = new CompactByteArray(temp, temp2);
-
- // read in numCols and numColGroups
- numCols = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- numColGroups = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
-
- // read in the row-number index
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- rowIndex = new short[l];
- for (int i = 0; i < l; i++, offset+=2) {
- rowIndex[i] = RuleBasedBreakIterator.getShort(buf, offset);
- }
-
- // load in the populated-cells bitmap: index first, then bitmap list
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- rowIndexFlagsIndex = new short[l];
- for (int i = 0; i < l; i++, offset+=2) {
- rowIndexFlagsIndex[i] = RuleBasedBreakIterator.getShort(buf, offset);
- }
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- rowIndexFlags = new int[l];
- for (int i = 0; i < l; i++, offset+=4) {
- rowIndexFlags[i] = RuleBasedBreakIterator.getInt(buf, offset);
- }
-
- // load in the row-shift index
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- rowIndexShifts = new byte[l];
- for (int i = 0; i < l; i++, offset++) {
- rowIndexShifts[i] = buf[offset];
- }
-
- // load in the actual state table
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- table = new short[l];
- for (int i = 0; i < l; i++, offset+=2) {
- table[i] = RuleBasedBreakIterator.getShort(buf, offset);
- }
-
- // finally, prepare the column map for supplementary characters
- l = RuleBasedBreakIterator.getInt(buf, offset);
- offset += 4;
- int[] temp3 = new int[l];
- for (int i = 0; i < l; i++, offset+=4) {
- temp3[i] = RuleBasedBreakIterator.getInt(buf, offset);
- }
- supplementaryCharColumnMap = new SupplementaryCharacterData(temp3);
- }
-
- //=========================================================================
- // access to the words
- //=========================================================================
-
- /**
- * Uses the column map to map the character to a column number, then
- * passes the row and column number to getNextState()
- * @param row The current state
- * @param ch The character whose column we're interested in
- * @return The new state to transition to
- */
- public final short getNextStateFromCharacter(int row, int ch) {
- int col;
- if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- col = columnMap.elementAt((char)ch);
- } else {
- col = supplementaryCharColumnMap.getValue(ch);
- }
- return getNextState(row, col);
- }
-
- /**
- * Returns the value in the cell with the specified (logical) row and
- * column numbers. In DictionaryBasedBreakIterator, the row number is
- * a state number, the column number is an input, and the return value
- * is the row number of the new state to transition to. (0 is the
- * "error" state, and -1 is the "end of word" state in a dictionary)
- * @param row The row number of the current state
- * @param col The column number of the input character (0 means "not a
- * dictionary character")
- * @return The row number of the new state to transition to
- */
- public final short getNextState(int row, int col) {
- if (cellIsPopulated(row, col)) {
- // we map from logical to physical row number by looking up the
- // mapping in rowIndex; we map from logical column number to
- // physical column number by looking up a shift value for this
- // logical row and offsetting the logical column number by
- // the shift amount. Then we can use internalAt() to actually
- // get the value out of the table.
- return internalAt(rowIndex[row], col + rowIndexShifts[row]);
- }
- else {
- return 0;
- }
- }
-
- /**
- * Given (logical) row and column numbers, returns true if the
- * cell in that position is populated
- */
- private boolean cellIsPopulated(int row, int col) {
- // look up the entry in the bitmap index for the specified row.
- // If it's a negative number, it's the column number of the only
- // populated cell in the row
- if (rowIndexFlagsIndex[row] < 0) {
- return col == -rowIndexFlagsIndex[row];
- }
-
- // if it's a positive number, it's the offset of an entry in the bitmap
- // list. If the table is more than 32 columns wide, the bitmap is stored
- // successive entries in the bitmap list, so we have to divide the column
- // number by 32 and offset the number we got out of the index by the result.
- // Once we have the appropriate piece of the bitmap, test the appropriate
- // bit and return the result.
- else {
- int flags = rowIndexFlags[rowIndexFlagsIndex[row] + (col >> 5)];
- return (flags & (1 << (col & 0x1f))) != 0;
- }
- }
-
- /**
- * Implementation of getNextState() when we know the specified cell is
- * populated.
- * @param row The PHYSICAL row number of the cell
- * @param col The PHYSICAL column number of the cell
- * @return The value stored in the cell
- */
- private short internalAt(int row, int col) {
- // the table is a one-dimensional array, so this just does the math necessary
- // to treat it as a two-dimensional array (we don't just use a two-dimensional
- // array because two-dimensional arrays are inefficient in Java)
- return table[row * numCols + col];
- }
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,8 @@
import java.util.MissingResourceException;
import java.util.Objects;
import java.util.Set;
+import sun.text.DictionaryBasedBreakIterator;
+import sun.text.RuleBasedBreakIterator;
/**
* Concrete implementation of the {@link java.text.spi.BreakIteratorProvider
@@ -153,29 +155,31 @@
}
private BreakIterator getBreakInstance(Locale locale,
- int type,
- String dataName,
- String dictionaryName) {
+ int type,
+ String ruleName,
+ String dictionaryName) {
Objects.requireNonNull(locale);
LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
String[] classNames = (String[]) lr.getBreakIteratorInfo("BreakIteratorClasses");
- String dataFile = (String) lr.getBreakIteratorInfo(dataName);
+ String ruleFile = (String) lr.getBreakIteratorInfo(ruleName);
+ byte[] ruleData = lr.getBreakIteratorResources(ruleName);
try {
switch (classNames[type]) {
case "RuleBasedBreakIterator":
- return new RuleBasedBreakIterator(
- lr.getBreakIteratorDataModule(), dataFile);
+ return new RuleBasedBreakIterator(ruleFile, ruleData);
+
case "DictionaryBasedBreakIterator":
String dictionaryFile = (String) lr.getBreakIteratorInfo(dictionaryName);
- return new DictionaryBasedBreakIterator(
- lr.getBreakIteratorDataModule(), dataFile, dictionaryFile);
+ byte[] dictionaryData = lr.getBreakIteratorResources(dictionaryName);
+ return new DictionaryBasedBreakIterator(ruleFile, ruleData,
+ dictionaryFile, dictionaryData);
default:
throw new IllegalArgumentException("Invalid break iterator class \"" +
classNames[type] + "\"");
}
- } catch (IOException | MissingResourceException | IllegalArgumentException e) {
+ } catch (MissingResourceException | IllegalArgumentException e) {
throw new InternalError(e.toString(), e);
}
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/locale/provider/DictionaryBasedBreakIterator.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/DictionaryBasedBreakIterator.java Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,524 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-
-package sun.util.locale.provider;
-
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.text.CharacterIterator;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-/**
- * A subclass of RuleBasedBreakIterator that adds the ability to use a dictionary
- * to further subdivide ranges of text beyond what is possible using just the
- * state-table-based algorithm. This is necessary, for example, to handle
- * word and line breaking in Thai, which doesn't use spaces between words. The
- * state-table-based algorithm used by RuleBasedBreakIterator is used to divide
- * up text as far as possible, and then contiguous ranges of letters are
- * repeatedly compared against a list of known words (i.e., the dictionary)
- * to divide them up into words.
- *
- * DictionaryBasedBreakIterator uses the same rule language as RuleBasedBreakIterator,
- * but adds one more special substitution name: <dictionary>. This substitution
- * name is used to identify characters in words in the dictionary. The idea is that
- * if the iterator passes over a chunk of text that includes two or more characters
- * in a row that are included in <dictionary>, it goes back through that range and
- * derives additional break positions (if possible) using the dictionary.
- *
- * DictionaryBasedBreakIterator is also constructed with the filename of a dictionary
- * file. It follows a prescribed search path to locate the dictionary (right now,
- * it looks for it in /com/ibm/text/resources in each directory in the classpath,
- * and won't find it in JAR files, but this location is likely to change). The
- * dictionary file is in a serialized binary format. We have a very primitive (and
- * slow) BuildDictionaryFile utility for creating dictionary files, but aren't
- * currently making it public. Contact us for help.
- */
-class DictionaryBasedBreakIterator extends RuleBasedBreakIterator {
-
- /**
- * a list of known words that is used to divide up contiguous ranges of letters,
- * stored in a compressed, indexed, format that offers fast access
- */
- private BreakDictionary dictionary;
-
- /**
- * a list of flags indicating which character categories are contained in
- * the dictionary file (this is used to determine which ranges of characters
- * to apply the dictionary to)
- */
- private boolean[] categoryFlags;
-
- /**
- * a temporary hiding place for the number of dictionary characters in the
- * last range passed over by next()
- */
- private int dictionaryCharCount;
-
- /**
- * when a range of characters is divided up using the dictionary, the break
- * positions that are discovered are stored here, preventing us from having
- * to use either the dictionary or the state table again until the iterator
- * leaves this range of text
- */
- private int[] cachedBreakPositions;
-
- /**
- * if cachedBreakPositions is not null, this indicates which item in the
- * cache the current iteration position refers to
- */
- private int positionInCache;
-
- /**
- * Constructs a DictionaryBasedBreakIterator.
- * @param module The module where the dictionary file resides
- * @param dictionaryFilename The filename of the dictionary file to use
- */
- DictionaryBasedBreakIterator(Module module, String dataFile, String dictionaryFile)
- throws IOException {
- super(module, dataFile);
- byte[] tmp = super.getAdditionalData();
- if (tmp != null) {
- prepareCategoryFlags(tmp);
- super.setAdditionalData(null);
- }
- dictionary = new BreakDictionary(module, dictionaryFile);
- }
-
- private void prepareCategoryFlags(byte[] data) {
- categoryFlags = new boolean[data.length];
- for (int i = 0; i < data.length; i++) {
- categoryFlags[i] = (data[i] == (byte)1) ? true : false;
- }
- }
-
- @Override
- public void setText(CharacterIterator newText) {
- super.setText(newText);
- cachedBreakPositions = null;
- dictionaryCharCount = 0;
- positionInCache = 0;
- }
-
- /**
- * Sets the current iteration position to the beginning of the text.
- * (i.e., the CharacterIterator's starting offset).
- * @return The offset of the beginning of the text.
- */
- @Override
- public int first() {
- cachedBreakPositions = null;
- dictionaryCharCount = 0;
- positionInCache = 0;
- return super.first();
- }
-
- /**
- * Sets the current iteration position to the end of the text.
- * (i.e., the CharacterIterator's ending offset).
- * @return The text's past-the-end offset.
- */
- @Override
- public int last() {
- cachedBreakPositions = null;
- dictionaryCharCount = 0;
- positionInCache = 0;
- return super.last();
- }
-
- /**
- * Advances the iterator one step backwards.
- * @return The position of the last boundary position before the
- * current iteration position
- */
- @Override
- public int previous() {
- CharacterIterator text = getText();
-
- // if we have cached break positions and we're still in the range
- // covered by them, just move one step backward in the cache
- if (cachedBreakPositions != null && positionInCache > 0) {
- --positionInCache;
- text.setIndex(cachedBreakPositions[positionInCache]);
- return cachedBreakPositions[positionInCache];
- }
-
- // otherwise, dump the cache and use the inherited previous() method to move
- // backward. This may fill up the cache with new break positions, in which
- // case we have to mark our position in the cache
- else {
- cachedBreakPositions = null;
- int result = super.previous();
- if (cachedBreakPositions != null) {
- positionInCache = cachedBreakPositions.length - 2;
- }
- return result;
- }
- }
-
- /**
- * Sets the current iteration position to the last boundary position
- * before the specified position.
- * @param offset The position to begin searching from
- * @return The position of the last boundary before "offset"
- */
- @Override
- public int preceding(int offset) {
- CharacterIterator text = getText();
- checkOffset(offset, text);
-
- // if we have no cached break positions, or "offset" is outside the
- // range covered by the cache, we can just call the inherited routine
- // (which will eventually call other routines in this class that may
- // refresh the cache)
- if (cachedBreakPositions == null || offset <= cachedBreakPositions[0] ||
- offset > cachedBreakPositions[cachedBreakPositions.length - 1]) {
- cachedBreakPositions = null;
- return super.preceding(offset);
- }
-
- // on the other hand, if "offset" is within the range covered by the cache,
- // then all we have to do is search the cache for the last break position
- // before "offset"
- else {
- positionInCache = 0;
- while (positionInCache < cachedBreakPositions.length
- && offset > cachedBreakPositions[positionInCache]) {
- ++positionInCache;
- }
- --positionInCache;
- text.setIndex(cachedBreakPositions[positionInCache]);
- return text.getIndex();
- }
- }
-
- /**
- * Sets the current iteration position to the first boundary position after
- * the specified position.
- * @param offset The position to begin searching forward from
- * @return The position of the first boundary after "offset"
- */
- @Override
- public int following(int offset) {
- CharacterIterator text = getText();
- checkOffset(offset, text);
-
- // if we have no cached break positions, or if "offset" is outside the
- // range covered by the cache, then dump the cache and call our
- // inherited following() method. This will call other methods in this
- // class that may refresh the cache.
- if (cachedBreakPositions == null || offset < cachedBreakPositions[0] ||
- offset >= cachedBreakPositions[cachedBreakPositions.length - 1]) {
- cachedBreakPositions = null;
- return super.following(offset);
- }
-
- // on the other hand, if "offset" is within the range covered by the
- // cache, then just search the cache for the first break position
- // after "offset"
- else {
- positionInCache = 0;
- while (positionInCache < cachedBreakPositions.length
- && offset >= cachedBreakPositions[positionInCache]) {
- ++positionInCache;
- }
- text.setIndex(cachedBreakPositions[positionInCache]);
- return text.getIndex();
- }
- }
-
- /**
- * This is the implementation function for next().
- */
- @Override
- protected int handleNext() {
- CharacterIterator text = getText();
-
- // if there are no cached break positions, or if we've just moved
- // off the end of the range covered by the cache, we have to dump
- // and possibly regenerate the cache
- if (cachedBreakPositions == null ||
- positionInCache == cachedBreakPositions.length - 1) {
-
- // start by using the inherited handleNext() to find a tentative return
- // value. dictionaryCharCount tells us how many dictionary characters
- // we passed over on our way to the tentative return value
- int startPos = text.getIndex();
- dictionaryCharCount = 0;
- int result = super.handleNext();
-
- // if we passed over more than one dictionary character, then we use
- // divideUpDictionaryRange() to regenerate the cached break positions
- // for the new range
- if (dictionaryCharCount > 1 && result - startPos > 1) {
- divideUpDictionaryRange(startPos, result);
- }
-
- // otherwise, the value we got back from the inherited fuction
- // is our return value, and we can dump the cache
- else {
- cachedBreakPositions = null;
- return result;
- }
- }
-
- // if the cache of break positions has been regenerated (or existed all
- // along), then just advance to the next break position in the cache
- // and return it
- if (cachedBreakPositions != null) {
- ++positionInCache;
- text.setIndex(cachedBreakPositions[positionInCache]);
- return cachedBreakPositions[positionInCache];
- }
- return -9999; // SHOULD NEVER GET HERE!
- }
-
- /**
- * Looks up a character category for a character.
- */
- @Override
- protected int lookupCategory(int c) {
- // this override of lookupCategory() exists only to keep track of whether we've
- // passed over any dictionary characters. It calls the inherited lookupCategory()
- // to do the real work, and then checks whether its return value is one of the
- // categories represented in the dictionary. If it is, bump the dictionary-
- // character count.
- int result = super.lookupCategory(c);
- if (result != RuleBasedBreakIterator.IGNORE && categoryFlags[result]) {
- ++dictionaryCharCount;
- }
- return result;
- }
-
- /**
- * This is the function that actually implements the dictionary-based
- * algorithm. Given the endpoints of a range of text, it uses the
- * dictionary to determine the positions of any boundaries in this
- * range. It stores all the boundary positions it discovers in
- * cachedBreakPositions so that we only have to do this work once
- * for each time we enter the range.
- */
- @SuppressWarnings("unchecked")
- private void divideUpDictionaryRange(int startPos, int endPos) {
- CharacterIterator text = getText();
-
- // the range we're dividing may begin or end with non-dictionary characters
- // (i.e., for line breaking, we may have leading or trailing punctuation
- // that needs to be kept with the word). Seek from the beginning of the
- // range to the first dictionary character
- text.setIndex(startPos);
- int c = getCurrent();
- int category = lookupCategory(c);
- while (category == IGNORE || !categoryFlags[category]) {
- c = getNext();
- category = lookupCategory(c);
- }
-
- // initialize. We maintain two stacks: currentBreakPositions contains
- // the list of break positions that will be returned if we successfully
- // finish traversing the whole range now. possibleBreakPositions lists
- // all other possible word ends we've passed along the way. (Whenever
- // we reach an error [a sequence of characters that can't begin any word
- // in the dictionary], we back up, possibly delete some breaks from
- // currentBreakPositions, move a break from possibleBreakPositions
- // to currentBreakPositions, and start over from there. This process
- // continues in this way until we either successfully make it all the way
- // across the range, or exhaust all of our combinations of break
- // positions.)
- Stack currentBreakPositions = new Stack<>();
- Stack possibleBreakPositions = new Stack<>();
- List wrongBreakPositions = new ArrayList<>();
-
- // the dictionary is implemented as a trie, which is treated as a state
- // machine. -1 represents the end of a legal word. Every word in the
- // dictionary is represented by a path from the root node to -1. A path
- // that ends in state 0 is an illegal combination of characters.
- int state = 0;
-
- // these two variables are used for error handling. We keep track of the
- // farthest we've gotten through the range being divided, and the combination
- // of breaks that got us that far. If we use up all possible break
- // combinations, the text contains an error or a word that's not in the
- // dictionary. In this case, we "bless" the break positions that got us the
- // farthest as real break positions, and then start over from scratch with
- // the character where the error occurred.
- int farthestEndPoint = text.getIndex();
- Stack bestBreakPositions = null;
-
- // initialize (we always exit the loop with a break statement)
- c = getCurrent();
- while (true) {
-
- // if we can transition to state "-1" from our current state, we're
- // on the last character of a legal word. Push that position onto
- // the possible-break-positions stack
- if (dictionary.getNextState(state, 0) == -1) {
- possibleBreakPositions.push(text.getIndex());
- }
-
- // look up the new state to transition to in the dictionary
- state = dictionary.getNextStateFromCharacter(state, c);
-
- // if the character we're sitting on causes us to transition to
- // the "end of word" state, then it was a non-dictionary character
- // and we've successfully traversed the whole range. Drop out
- // of the loop.
- if (state == -1) {
- currentBreakPositions.push(text.getIndex());
- break;
- }
-
- // if the character we're sitting on causes us to transition to
- // the error state, or if we've gone off the end of the range
- // without transitioning to the "end of word" state, we've hit
- // an error...
- else if (state == 0 || text.getIndex() >= endPos) {
-
- // if this is the farthest we've gotten, take note of it in
- // case there's an error in the text
- if (text.getIndex() > farthestEndPoint) {
- farthestEndPoint = text.getIndex();
-
- @SuppressWarnings("unchecked")
- Stack currentBreakPositionsCopy = (Stack) currentBreakPositions.clone();
-
- bestBreakPositions = currentBreakPositionsCopy;
- }
-
- // wrongBreakPositions is a list of all break positions
- // we've tried starting that didn't allow us to traverse
- // all the way through the text. Every time we pop a
- // break position off of currentBreakPositions, we put it
- // into wrongBreakPositions to avoid trying it again later.
- // If we make it to this spot, we're either going to back
- // up to a break in possibleBreakPositions and try starting
- // over from there, or we've exhausted all possible break
- // positions and are going to do the fallback procedure.
- // This loop prevents us from messing with anything in
- // possibleBreakPositions that didn't work as a starting
- // point the last time we tried it (this is to prevent a bunch of
- // repetitive checks from slowing down some extreme cases)
- while (!possibleBreakPositions.isEmpty()
- && wrongBreakPositions.contains(possibleBreakPositions.peek())) {
- possibleBreakPositions.pop();
- }
-
- // if we've used up all possible break-position combinations, there's
- // an error or an unknown word in the text. In this case, we start
- // over, treating the farthest character we've reached as the beginning
- // of the range, and "blessing" the break positions that got us that
- // far as real break positions
- if (possibleBreakPositions.isEmpty()) {
- if (bestBreakPositions != null) {
- currentBreakPositions = bestBreakPositions;
- if (farthestEndPoint < endPos) {
- text.setIndex(farthestEndPoint + 1);
- }
- else {
- break;
- }
- }
- else {
- if ((currentBreakPositions.size() == 0 ||
- currentBreakPositions.peek().intValue() != text.getIndex())
- && text.getIndex() != startPos) {
- currentBreakPositions.push(text.getIndex());
- }
- getNext();
- currentBreakPositions.push(text.getIndex());
- }
- }
-
- // if we still have more break positions we can try, then promote the
- // last break in possibleBreakPositions into currentBreakPositions,
- // and get rid of all entries in currentBreakPositions that come after
- // it. Then back up to that position and start over from there (i.e.,
- // treat that position as the beginning of a new word)
- else {
- Integer temp = possibleBreakPositions.pop();
- Integer temp2 = null;
- while (!currentBreakPositions.isEmpty() && temp.intValue() <
- currentBreakPositions.peek().intValue()) {
- temp2 = currentBreakPositions.pop();
- wrongBreakPositions.add(temp2);
- }
- currentBreakPositions.push(temp);
- text.setIndex(currentBreakPositions.peek().intValue());
- }
-
- // re-sync "c" for the next go-round, and drop out of the loop if
- // we've made it off the end of the range
- c = getCurrent();
- if (text.getIndex() >= endPos) {
- break;
- }
- }
-
- // if we didn't hit any exceptional conditions on this last iteration,
- // just advance to the next character and loop
- else {
- c = getNext();
- }
- }
-
- // dump the last break position in the list, and replace it with the actual
- // end of the range (which may be the same character, or may be further on
- // because the range actually ended with non-dictionary characters we want to
- // keep with the word)
- if (!currentBreakPositions.isEmpty()) {
- currentBreakPositions.pop();
- }
- currentBreakPositions.push(endPos);
-
- // create a regular array to hold the break positions and copy
- // the break positions from the stack to the array (in addition,
- // our starting position goes into this array as a break position).
- // This array becomes the cache of break positions used by next()
- // and previous(), so this is where we actually refresh the cache.
- cachedBreakPositions = new int[currentBreakPositions.size() + 1];
- cachedBreakPositions[0] = startPos;
-
- for (int i = 0; i < currentBreakPositions.size(); i++) {
- cachedBreakPositions[i + 1] = currentBreakPositions.elementAt(i).intValue();
- }
- positionInCache = 0;
- }
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,6 @@
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
-import java.lang.reflect.Module;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.LinkedHashSet;
@@ -113,13 +112,14 @@
if (data == null || ((biInfo = data.get()) == null)) {
biInfo = localeData.getBreakIteratorInfo(locale).getObject(key);
cache.put(cacheKey, new ResourceReference(cacheKey, biInfo, referenceQueue));
- }
+ }
return biInfo;
}
- Module getBreakIteratorDataModule() {
- return localeData.getBreakIteratorInfo(locale).getClass().getModule();
+ @SuppressWarnings("unchecked")
+ byte[] getBreakIteratorResources(String key) {
+ return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key);
}
int getCalendarData(String key) {
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/locale/provider/RuleBasedBreakIterator.java
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/RuleBasedBreakIterator.java Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1198 +0,0 @@
-/*
- * Copyright (c) 1999, 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.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-
-package sun.util.locale.provider;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.text.BreakIterator;
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.MissingResourceException;
-import sun.text.CompactByteArray;
-import sun.text.SupplementaryCharacterData;
-
-/**
- * A subclass of BreakIterator whose behavior is specified using a list of rules.
- *
- * There are two kinds of rules, which are separated by semicolons: substitutions
- * and regular expressions.
- *
- * A substitution rule defines a name that can be used in place of an expression. It
- * consists of a name, which is a string of characters contained in angle brackets, an equals
- * sign, and an expression. (There can be no whitespace on either side of the equals sign.)
- * To keep its syntactic meaning intact, the expression must be enclosed in parentheses or
- * square brackets. A substitution is visible after its definition, and is filled in using
- * simple textual substitution. Substitution definitions can contain other substitutions, as
- * long as those substitutions have been defined first. Substitutions are generally used to
- * make the regular expressions (which can get quite complex) shorted and easier to read.
- * They typically define either character categories or commonly-used subexpressions.
- *
- * There is one special substitution. If the description defines a substitution
- * called "<ignore>", the expression must be a [] expression, and the
- * expression defines a set of characters (the "ignore characters") that
- * will be transparent to the BreakIterator. A sequence of characters will break the
- * same way it would if any ignore characters it contains are taken out. Break
- * positions never occur befoer ignore characters.
- *
- * A regular expression uses a subset of the normal Unix regular-expression syntax, and
- * defines a sequence of characters to be kept together. With one significant exception, the
- * iterator uses a longest-possible-match algorithm when matching text to regular
- * expressions. The iterator also treats descriptions containing multiple regular expressions
- * as if they were ORed together (i.e., as if they were separated by |).
- *
- * The special characters recognized by the regular-expression parser are as follows:
- *
- *
- *
- *
- * * |
- * Specifies that the expression preceding the asterisk may occur any number
- * of times (including not at all). |
- *
- *
- * {} |
- * Encloses a sequence of characters that is optional. |
- *
- *
- * () |
- * Encloses a sequence of characters. If followed by *, the sequence
- * repeats. Otherwise, the parentheses are just a grouping device and a way to delimit
- * the ends of expressions containing |. |
- *
- *
- * | |
- * Separates two alternative sequences of characters. Either one
- * sequence or the other, but not both, matches this expression. The | character can
- * only occur inside (). |
- *
- *
- * . |
- * Matches any character. |
- *
- *
- * *? |
- * Specifies a non-greedy asterisk. *? works the same way as *, except
- * when there is overlap between the last group of characters in the expression preceding the
- * * and the first group of characters following the *. When there is this kind of
- * overlap, * will match the longest sequence of characters that match the expression before
- * the *, and *? will match the shortest sequence of characters matching the expression
- * before the *?. For example, if you have "xxyxyyyxyxyxxyxyxyy" in the text,
- * "x[xy]*x" will match through to the last x (i.e., "xxyxyyyxyxyxxyxyxyy",
- * but "x[xy]*?x" will only match the first two xes ("xxyxyyyxyxyxxyxyxyy"). |
- *
- *
- * [] |
- * Specifies a group of alternative characters. A [] expression will
- * match any single character that is specified in the [] expression. For more on the
- * syntax of [] expressions, see below. |
- *
- *
- * / |
- * Specifies where the break position should go if text matches this
- * expression. (e.g., "[a-z]*/[:Zs:]*[1-0]" will match if the iterator sees a run
- * of letters, followed by a run of whitespace, followed by a digit, but the break position
- * will actually go before the whitespace). Expressions that don't contain / put the
- * break position at the end of the matching text. |
- *
- *
- * \ |
- * Escape character. The \ itself is ignored, but causes the next
- * character to be treated as literal character. This has no effect for many
- * characters, but for the characters listed above, this deprives them of their special
- * meaning. (There are no special escape sequences for Unicode characters, or tabs and
- * newlines; these are all handled by a higher-level protocol. In a Java string,
- * "\n" will be converted to a literal newline character by the time the
- * regular-expression parser sees it. Of course, this means that \ sequences that are
- * visible to the regexp parser must be written as \\ when inside a Java string.) All
- * characters in the ASCII range except for letters, digits, and control characters are
- * reserved characters to the parser and must be preceded by \ even if they currently don't
- * mean anything. |
- *
- *
- * ! |
- * If ! appears at the beginning of a regular expression, it tells the regexp
- * parser that this expression specifies the backwards-iteration behavior of the iterator,
- * and not its normal iteration behavior. This is generally only used in situations
- * where the automatically-generated backwards-iteration brhavior doesn't produce
- * satisfactory results and must be supplemented with extra client-specified rules. |
- *
- *
- * (all others) |
- * All other characters are treated as literal characters, which must match
- * the corresponding character(s) in the text exactly. |
- *
- *
- *
- *
- * Within a [] expression, a number of other special characters can be used to specify
- * groups of characters:
- *
- *
- *
- *
- * - |
- * Specifies a range of matching characters. For example
- * "[a-p]" matches all lowercase Latin letters from a to p (inclusive). The -
- * sign specifies ranges of continuous Unicode numeric values, not ranges of characters in a
- * language's alphabetical order: "[a-z]" doesn't include capital letters, nor does
- * it include accented letters such as a-umlaut. |
- *
- *
- * :: |
- * A pair of colons containing a one- or two-letter code matches all
- * characters in the corresponding Unicode category. The two-letter codes are the same
- * as the two-letter codes in the Unicode database (for example, "[:Sc::Sm:]"
- * matches all currency symbols and all math symbols). Specifying a one-letter code is
- * the same as specifying all two-letter codes that begin with that letter (for example,
- * "[:L:]" matches all letters, and is equivalent to
- * "[:Lu::Ll::Lo::Lm::Lt:]"). Anything other than a valid two-letter Unicode
- * category code or a single letter that begins a Unicode category code is illegal within
- * colons. |
- *
- *
- * [] |
- * [] expressions can nest. This has no effect, except when used in
- * conjunction with the ^ token. |
- *
- *
- * ^ |
- * Excludes the character (or the characters in the [] expression) following
- * it from the group of characters. For example, "[a-z^p]" matches all Latin
- * lowercase letters except p. "[:L:^[\u4e00-\u9fff]]" matches all letters
- * except the Han ideographs. |
- *
- *
- * (all others) |
- * All other characters are treated as literal characters. (For
- * example, "[aeiou]" specifies just the letters a, e, i, o, and u.) |
- *
- *
- *
- *
- * For a more complete explanation, see http://www.ibm.com/java/education/boundaries/boundaries.html.
- * For examples, see the resource data (which is annotated).
- *
- * @author Richard Gillam
- */
-class RuleBasedBreakIterator extends BreakIterator {
-
- /**
- * A token used as a character-category value to identify ignore characters
- */
- protected static final byte IGNORE = -1;
-
- /**
- * The state number of the starting state
- */
- private static final short START_STATE = 1;
-
- /**
- * The state-transition value indicating "stop"
- */
- private static final short STOP_STATE = 0;
-
- /**
- * Magic number for the BreakIterator data file format.
- */
- static final byte[] LABEL = {
- (byte)'B', (byte)'I', (byte)'d', (byte)'a', (byte)'t', (byte)'a',
- (byte)'\0'
- };
- static final int LABEL_LENGTH = LABEL.length;
-
- /**
- * Version number of the dictionary that was read in.
- */
- static final byte supportedVersion = 1;
-
- /**
- * Header size in byte count
- */
- private static final int HEADER_LENGTH = 36;
-
- /**
- * An array length of indices for BMP characters
- */
- private static final int BMP_INDICES_LENGTH = 512;
-
- /**
- * Tables that indexes from character values to character category numbers
- */
- private CompactByteArray charCategoryTable = null;
- private SupplementaryCharacterData supplementaryCharCategoryTable = null;
-
- /**
- * The table of state transitions used for forward iteration
- */
- private short[] stateTable = null;
-
- /**
- * The table of state transitions used to sync up the iterator with the
- * text in backwards and random-access iteration
- */
- private short[] backwardsStateTable = null;
-
- /**
- * A list of flags indicating which states in the state table are accepting
- * ("end") states
- */
- private boolean[] endStates = null;
-
- /**
- * A list of flags indicating which states in the state table are
- * lookahead states (states which turn lookahead on and off)
- */
- private boolean[] lookaheadStates = null;
-
- /**
- * A table for additional data. May be used by a subclass of
- * RuleBasedBreakIterator.
- */
- private byte[] additionalData = null;
-
- /**
- * The number of character categories (and, thus, the number of columns in
- * the state tables)
- */
- private int numCategories;
-
- /**
- * The character iterator through which this BreakIterator accesses the text
- */
- private CharacterIterator text = null;
-
- /**
- * A CRC32 value of all data in datafile
- */
- private long checksum;
-
- //=======================================================================
- // constructors
- //=======================================================================
-
- /**
- * Constructs a RuleBasedBreakIterator according to the module and the datafile
- * provided.
- */
- RuleBasedBreakIterator(Module module, String datafile)
- throws IOException, MissingResourceException {
- readTables(module, datafile);
- }
-
- /**
- * Read datafile. The datafile's format is as follows:
- *
- * BreakIteratorData {
- * u1 magic[7];
- * u1 version;
- * u4 totalDataSize;
- * header_info header;
- * body value;
- * }
- *
- * totalDataSize
is the summation of the size of
- * header_info
and body
in byte count.
- *
- * In header
, each field except for checksum implies the
- * length of each field. Since BMPdataLength
is a fixed-length
- * data(512 entries), its length isn't included in header
.
- * checksum
is a CRC32 value of all in body
.
- *
- * header_info {
- * u4 stateTableLength;
- * u4 backwardsStateTableLength;
- * u4 endStatesLength;
- * u4 lookaheadStatesLength;
- * u4 BMPdataLength;
- * u4 nonBMPdataLength;
- * u4 additionalDataLength;
- * u8 checksum;
- * }
- *
- *
- *
- * Finally, BMPindices
and BMPdata
are set to
- * charCategoryTable
. nonBMPdata
is set to
- * supplementaryCharCategoryTable
.
- *
- * body {
- * u2 stateTable[stateTableLength];
- * u2 backwardsStateTable[backwardsStateTableLength];
- * u1 endStates[endStatesLength];
- * u1 lookaheadStates[lookaheadStatesLength];
- * u2 BMPindices[512];
- * u1 BMPdata[BMPdataLength];
- * u4 nonBMPdata[numNonBMPdataLength];
- * u1 additionalData[additionalDataLength];
- * }
- *
- */
- protected final void readTables(Module module, String datafile)
- throws IOException, MissingResourceException {
-
- byte[] buffer = readFile(module, datafile);
-
- /* Read header_info. */
- int stateTableLength = getInt(buffer, 0);
- int backwardsStateTableLength = getInt(buffer, 4);
- int endStatesLength = getInt(buffer, 8);
- int lookaheadStatesLength = getInt(buffer, 12);
- int BMPdataLength = getInt(buffer, 16);
- int nonBMPdataLength = getInt(buffer, 20);
- int additionalDataLength = getInt(buffer, 24);
- checksum = getLong(buffer, 28);
-
- /* Read stateTable[numCategories * numRows] */
- stateTable = new short[stateTableLength];
- int offset = HEADER_LENGTH;
- for (int i = 0; i < stateTableLength; i++, offset+=2) {
- stateTable[i] = getShort(buffer, offset);
- }
-
- /* Read backwardsStateTable[numCategories * numRows] */
- backwardsStateTable = new short[backwardsStateTableLength];
- for (int i = 0; i < backwardsStateTableLength; i++, offset+=2) {
- backwardsStateTable[i] = getShort(buffer, offset);
- }
-
- /* Read endStates[numRows] */
- endStates = new boolean[endStatesLength];
- for (int i = 0; i < endStatesLength; i++, offset++) {
- endStates[i] = buffer[offset] == 1;
- }
-
- /* Read lookaheadStates[numRows] */
- lookaheadStates = new boolean[lookaheadStatesLength];
- for (int i = 0; i < lookaheadStatesLength; i++, offset++) {
- lookaheadStates[i] = buffer[offset] == 1;
- }
-
- /* Read a category table and indices for BMP characters. */
- short[] temp1 = new short[BMP_INDICES_LENGTH]; // BMPindices
- for (int i = 0; i < BMP_INDICES_LENGTH; i++, offset+=2) {
- temp1[i] = getShort(buffer, offset);
- }
- byte[] temp2 = new byte[BMPdataLength]; // BMPdata
- System.arraycopy(buffer, offset, temp2, 0, BMPdataLength);
- offset += BMPdataLength;
- charCategoryTable = new CompactByteArray(temp1, temp2);
-
- /* Read a category table for non-BMP characters. */
- int[] temp3 = new int[nonBMPdataLength];
- for (int i = 0; i < nonBMPdataLength; i++, offset+=4) {
- temp3[i] = getInt(buffer, offset);
- }
- supplementaryCharCategoryTable = new SupplementaryCharacterData(temp3);
-
- /* Read additional data */
- if (additionalDataLength > 0) {
- additionalData = new byte[additionalDataLength];
- System.arraycopy(buffer, offset, additionalData, 0, additionalDataLength);
- }
-
- /* Set numCategories */
- numCategories = stateTable.length / endStates.length;
- }
-
- protected byte[] readFile(final Module module, final String datafile)
- throws IOException, MissingResourceException {
-
- BufferedInputStream is;
- try {
- PrivilegedExceptionAction pa = () -> {
- String pathName = "jdk.localedata".equals(module.getName()) ?
- "sun/text/resources/ext/" :
- "sun/text/resources/";
- InputStream in = module.getResourceAsStream(pathName + datafile);
- if (in == null) {
- // Try to load the file with "java.base" module instance. Assumption
- // here is that the fall back data files to be read should reside in
- // java.base.
- in = RuleBasedBreakIterator.class.getModule().getResourceAsStream("sun/text/resources/" + datafile);
- }
-
- return new BufferedInputStream(in);
- };
- is = AccessController.doPrivileged(pa);
- } catch (PrivilegedActionException e) {
- throw new InternalError(e.toString(), e);
- }
-
- int offset = 0;
-
- /* First, read magic, version, and header_info. */
- int len = LABEL_LENGTH + 5;
- byte[] buf = new byte[len];
- if (is.read(buf) != len) {
- throw new MissingResourceException("Wrong header length",
- datafile, "");
- }
-
- /* Validate the magic number. */
- for (int i = 0; i < LABEL_LENGTH; i++, offset++) {
- if (buf[offset] != LABEL[offset]) {
- throw new MissingResourceException("Wrong magic number",
- datafile, "");
- }
- }
-
- /* Validate the version number. */
- if (buf[offset] != supportedVersion) {
- throw new MissingResourceException("Unsupported version(" + buf[offset] + ")",
- datafile, "");
- }
-
- /* Read data: totalDataSize + 8(for checksum) */
- len = getInt(buf, ++offset);
- buf = new byte[len];
- if (is.read(buf) != len) {
- throw new MissingResourceException("Wrong data length",
- datafile, "");
- }
-
- is.close();
-
- return buf;
- }
-
- byte[] getAdditionalData() {
- return additionalData;
- }
-
- void setAdditionalData(byte[] b) {
- additionalData = b;
- }
-
- //=======================================================================
- // boilerplate
- //=======================================================================
- /**
- * Clones this iterator.
- * @return A newly-constructed RuleBasedBreakIterator with the same
- * behavior as this one.
- */
- @Override
- public Object clone() {
- RuleBasedBreakIterator result = (RuleBasedBreakIterator) super.clone();
- if (text != null) {
- result.text = (CharacterIterator) text.clone();
- }
- return result;
- }
-
- /**
- * Returns true if both BreakIterators are of the same class, have the same
- * rules, and iterate over the same text.
- */
- @Override
- public boolean equals(Object that) {
- try {
- if (that == null) {
- return false;
- }
-
- RuleBasedBreakIterator other = (RuleBasedBreakIterator) that;
- if (checksum != other.checksum) {
- return false;
- }
- if (text == null) {
- return other.text == null;
- } else {
- return text.equals(other.text);
- }
- }
- catch(ClassCastException e) {
- return false;
- }
- }
-
- /**
- * Returns text
- */
- @Override
- public String toString() {
- return "[checksum=0x" + Long.toHexString(checksum) + ']';
- }
-
- /**
- * Compute a hashcode for this BreakIterator
- * @return A hash code
- */
- @Override
- public int hashCode() {
- return (int)checksum;
- }
-
- //=======================================================================
- // BreakIterator overrides
- //=======================================================================
-
- /**
- * Sets the current iteration position to the beginning of the text.
- * (i.e., the CharacterIterator's starting offset).
- * @return The offset of the beginning of the text.
- */
- @Override
- public int first() {
- CharacterIterator t = getText();
-
- t.first();
- return t.getIndex();
- }
-
- /**
- * Sets the current iteration position to the end of the text.
- * (i.e., the CharacterIterator's ending offset).
- * @return The text's past-the-end offset.
- */
- @Override
- public int last() {
- CharacterIterator t = getText();
-
- // I'm not sure why, but t.last() returns the offset of the last character,
- // rather than the past-the-end offset
- t.setIndex(t.getEndIndex());
- return t.getIndex();
- }
-
- /**
- * Advances the iterator either forward or backward the specified number of steps.
- * Negative values move backward, and positive values move forward. This is
- * equivalent to repeatedly calling next() or previous().
- * @param n The number of steps to move. The sign indicates the direction
- * (negative is backwards, and positive is forwards).
- * @return The character offset of the boundary position n boundaries away from
- * the current one.
- */
- @Override
- public int next(int n) {
- int result = current();
- while (n > 0) {
- result = handleNext();
- --n;
- }
- while (n < 0) {
- result = previous();
- ++n;
- }
- return result;
- }
-
- /**
- * Advances the iterator to the next boundary position.
- * @return The position of the first boundary after this one.
- */
- @Override
- public int next() {
- return handleNext();
- }
-
- private int cachedLastKnownBreak = BreakIterator.DONE;
-
- /**
- * Advances the iterator backwards, to the last boundary preceding this one.
- * @return The position of the last boundary position preceding this one.
- */
- @Override
- public int previous() {
- // if we're already sitting at the beginning of the text, return DONE
- CharacterIterator text = getText();
- if (current() == text.getBeginIndex()) {
- return BreakIterator.DONE;
- }
-
- // set things up. handlePrevious() will back us up to some valid
- // break position before the current position (we back our internal
- // iterator up one step to prevent handlePrevious() from returning
- // the current position), but not necessarily the last one before
- // where we started
- int start = current();
- int lastResult = cachedLastKnownBreak;
- if (lastResult >= start || lastResult <= BreakIterator.DONE) {
- getPrevious();
- lastResult = handlePrevious();
- } else {
- //it might be better to check if handlePrevious() give us closer
- //safe value but handlePrevious() is slow too
- //So, this has to be done carefully
- text.setIndex(lastResult);
- }
- int result = lastResult;
-
- // iterate forward from the known break position until we pass our
- // starting point. The last break position before the starting
- // point is our return value
- while (result != BreakIterator.DONE && result < start) {
- lastResult = result;
- result = handleNext();
- }
-
- // set the current iteration position to be the last break position
- // before where we started, and then return that value
- text.setIndex(lastResult);
- cachedLastKnownBreak = lastResult;
- return lastResult;
- }
-
- /**
- * Returns previous character
- */
- private int getPrevious() {
- char c2 = text.previous();
- if (Character.isLowSurrogate(c2) &&
- text.getIndex() > text.getBeginIndex()) {
- char c1 = text.previous();
- if (Character.isHighSurrogate(c1)) {
- return Character.toCodePoint(c1, c2);
- } else {
- text.next();
- }
- }
- return (int)c2;
- }
-
- /**
- * Returns current character
- */
- int getCurrent() {
- char c1 = text.current();
- if (Character.isHighSurrogate(c1) &&
- text.getIndex() < text.getEndIndex()) {
- char c2 = text.next();
- text.previous();
- if (Character.isLowSurrogate(c2)) {
- return Character.toCodePoint(c1, c2);
- }
- }
- return (int)c1;
- }
-
- /**
- * Returns the count of next character.
- */
- private int getCurrentCodePointCount() {
- char c1 = text.current();
- if (Character.isHighSurrogate(c1) &&
- text.getIndex() < text.getEndIndex()) {
- char c2 = text.next();
- text.previous();
- if (Character.isLowSurrogate(c2)) {
- return 2;
- }
- }
- return 1;
- }
-
- /**
- * Returns next character
- */
- int getNext() {
- int index = text.getIndex();
- int endIndex = text.getEndIndex();
- if (index == endIndex ||
- (index += getCurrentCodePointCount()) >= endIndex) {
- return CharacterIterator.DONE;
- }
- text.setIndex(index);
- return getCurrent();
- }
-
- /**
- * Returns the position of next character.
- */
- private int getNextIndex() {
- int index = text.getIndex() + getCurrentCodePointCount();
- int endIndex = text.getEndIndex();
- if (index > endIndex) {
- return endIndex;
- } else {
- return index;
- }
- }
-
- /**
- * Throw IllegalArgumentException unless begin <= offset < end.
- */
- protected static final void checkOffset(int offset, CharacterIterator text) {
- if (offset < text.getBeginIndex() || offset > text.getEndIndex()) {
- throw new IllegalArgumentException("offset out of bounds");
- }
- }
-
- /**
- * Sets the iterator to refer to the first boundary position following
- * the specified position.
- * @offset The position from which to begin searching for a break position.
- * @return The position of the first break after the current position.
- */
- @Override
- public int following(int offset) {
-
- CharacterIterator text = getText();
- checkOffset(offset, text);
-
- // Set our internal iteration position (temporarily)
- // to the position passed in. If this is the _beginning_ position,
- // then we can just use next() to get our return value
- text.setIndex(offset);
- if (offset == text.getBeginIndex()) {
- cachedLastKnownBreak = handleNext();
- return cachedLastKnownBreak;
- }
-
- // otherwise, we have to sync up first. Use handlePrevious() to back
- // us up to a known break position before the specified position (if
- // we can determine that the specified position is a break position,
- // we don't back up at all). This may or may not be the last break
- // position at or before our starting position. Advance forward
- // from here until we've passed the starting position. The position
- // we stop on will be the first break position after the specified one.
- int result = cachedLastKnownBreak;
- if (result >= offset || result <= BreakIterator.DONE) {
- result = handlePrevious();
- } else {
- //it might be better to check if handlePrevious() give us closer
- //safe value but handlePrevious() is slow too
- //So, this has to be done carefully
- text.setIndex(result);
- }
- while (result != BreakIterator.DONE && result <= offset) {
- result = handleNext();
- }
- cachedLastKnownBreak = result;
- return result;
- }
-
- /**
- * Sets the iterator to refer to the last boundary position before the
- * specified position.
- * @offset The position to begin searching for a break from.
- * @return The position of the last boundary before the starting position.
- */
- @Override
- public int preceding(int offset) {
- // if we start by updating the current iteration position to the
- // position specified by the caller, we can just use previous()
- // to carry out this operation
- CharacterIterator text = getText();
- checkOffset(offset, text);
- text.setIndex(offset);
- return previous();
- }
-
- /**
- * Returns true if the specified position is a boundary position. As a side
- * effect, leaves the iterator pointing to the first boundary position at
- * or after "offset".
- * @param offset the offset to check.
- * @return True if "offset" is a boundary position.
- */
- @Override
- public boolean isBoundary(int offset) {
- CharacterIterator text = getText();
- checkOffset(offset, text);
- if (offset == text.getBeginIndex()) {
- return true;
- }
-
- // to check whether this is a boundary, we can use following() on the
- // position before the specified one and return true if the position we
- // get back is the one the user specified
- else {
- return following(offset - 1) == offset;
- }
- }
-
- /**
- * Returns the current iteration position.
- * @return The current iteration position.
- */
- @Override
- public int current() {
- return getText().getIndex();
- }
-
- /**
- * Return a CharacterIterator over the text being analyzed. This version
- * of this method returns the actual CharacterIterator we're using internally.
- * Changing the state of this iterator can have undefined consequences. If
- * you need to change it, clone it first.
- * @return An iterator over the text being analyzed.
- */
- @Override
- public CharacterIterator getText() {
- // The iterator is initialized pointing to no text at all, so if this
- // function is called while we're in that state, we have to fudge an
- // iterator to return.
- if (text == null) {
- text = new StringCharacterIterator("");
- }
- return text;
- }
-
- /**
- * Set the iterator to analyze a new piece of text. This function resets
- * the current iteration position to the beginning of the text.
- * @param newText An iterator over the text to analyze.
- */
- @Override
- public void setText(CharacterIterator newText) {
- // Test iterator to see if we need to wrap it in a SafeCharIterator.
- // The correct behavior for CharacterIterators is to allow the
- // position to be set to the endpoint of the iterator. Many
- // CharacterIterators do not uphold this, so this is a workaround
- // to permit them to use this class.
- int end = newText.getEndIndex();
- boolean goodIterator;
- try {
- newText.setIndex(end); // some buggy iterators throw an exception here
- goodIterator = newText.getIndex() == end;
- }
- catch(IllegalArgumentException e) {
- goodIterator = false;
- }
-
- if (goodIterator) {
- text = newText;
- }
- else {
- text = new SafeCharIterator(newText);
- }
- text.first();
-
- cachedLastKnownBreak = BreakIterator.DONE;
- }
-
-
- //=======================================================================
- // implementation
- //=======================================================================
-
- /**
- * This method is the actual implementation of the next() method. All iteration
- * vectors through here. This method initializes the state machine to state 1
- * and advances through the text character by character until we reach the end
- * of the text or the state machine transitions to state 0. We update our return
- * value every time the state machine passes through a possible end state.
- */
- protected int handleNext() {
- // if we're already at the end of the text, return DONE.
- CharacterIterator text = getText();
- if (text.getIndex() == text.getEndIndex()) {
- return BreakIterator.DONE;
- }
-
- // no matter what, we always advance at least one character forward
- int result = getNextIndex();
- int lookaheadResult = 0;
-
- // begin in state 1
- int state = START_STATE;
- int category;
- int c = getCurrent();
-
- // loop until we reach the end of the text or transition to state 0
- while (c != CharacterIterator.DONE && state != STOP_STATE) {
-
- // look up the current character's character category (which tells us
- // which column in the state table to look at)
- category = lookupCategory(c);
-
- // if the character isn't an ignore character, look up a state
- // transition in the state table
- if (category != IGNORE) {
- state = lookupState(state, category);
- }
-
- // if the state we've just transitioned to is a lookahead state,
- // (but not also an end state), save its position. If it's
- // both a lookahead state and an end state, update the break position
- // to the last saved lookup-state position
- if (lookaheadStates[state]) {
- if (endStates[state]) {
- result = lookaheadResult;
- }
- else {
- lookaheadResult = getNextIndex();
- }
- }
-
- // otherwise, if the state we've just transitioned to is an accepting
- // state, update the break position to be the current iteration position
- else {
- if (endStates[state]) {
- result = getNextIndex();
- }
- }
-
- c = getNext();
- }
-
- // if we've run off the end of the text, and the very last character took us into
- // a lookahead state, advance the break position to the lookahead position
- // (the theory here is that if there are no characters at all after the lookahead
- // position, that always matches the lookahead criteria)
- if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) {
- result = lookaheadResult;
- }
-
- text.setIndex(result);
- return result;
- }
-
- /**
- * This method backs the iterator back up to a "safe position" in the text.
- * This is a position that we know, without any context, must be a break position.
- * The various calling methods then iterate forward from this safe position to
- * the appropriate position to return. (For more information, see the description
- * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
- */
- protected int handlePrevious() {
- CharacterIterator text = getText();
- int state = START_STATE;
- int category = 0;
- int lastCategory = 0;
- int c = getCurrent();
-
- // loop until we reach the beginning of the text or transition to state 0
- while (c != CharacterIterator.DONE && state != STOP_STATE) {
-
- // save the last character's category and look up the current
- // character's category
- lastCategory = category;
- category = lookupCategory(c);
-
- // if the current character isn't an ignore character, look up a
- // state transition in the backwards state table
- if (category != IGNORE) {
- state = lookupBackwardState(state, category);
- }
-
- // then advance one character backwards
- c = getPrevious();
- }
-
- // if we didn't march off the beginning of the text, we're either one or two
- // positions away from the real break position. (One because of the call to
- // previous() at the end of the loop above, and another because the character
- // that takes us into the stop state will always be the character BEFORE
- // the break position.)
- if (c != CharacterIterator.DONE) {
- if (lastCategory != IGNORE) {
- getNext();
- getNext();
- }
- else {
- getNext();
- }
- }
- return text.getIndex();
- }
-
- /**
- * Looks up a character's category (i.e., its category for breaking purposes,
- * not its Unicode category)
- */
- protected int lookupCategory(int c) {
- if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- return charCategoryTable.elementAt((char)c);
- } else {
- return supplementaryCharCategoryTable.getValue(c);
- }
- }
-
- /**
- * Given a current state and a character category, looks up the
- * next state to transition to in the state table.
- */
- protected int lookupState(int state, int category) {
- return stateTable[state * numCategories + category];
- }
-
- /**
- * Given a current state and a character category, looks up the
- * next state to transition to in the backwards state table.
- */
- protected int lookupBackwardState(int state, int category) {
- return backwardsStateTable[state * numCategories + category];
- }
-
- static long getLong(byte[] buf, int offset) {
- long num = buf[offset]&0xFF;
- for (int i = 1; i < 8; i++) {
- num = num<<8 | (buf[offset+i]&0xFF);
- }
- return num;
- }
-
- static int getInt(byte[] buf, int offset) {
- int num = buf[offset]&0xFF;
- for (int i = 1; i < 4; i++) {
- num = num<<8 | (buf[offset+i]&0xFF);
- }
- return num;
- }
-
- static short getShort(byte[] buf, int offset) {
- short num = (short)(buf[offset]&0xFF);
- num = (short)(num<<8 | (buf[offset+1]&0xFF));
- return num;
- }
-
- /*
- * This class exists to work around a bug in incorrect implementations
- * of CharacterIterator, which incorrectly handle setIndex(endIndex).
- * This iterator relies only on base.setIndex(n) where n is less than
- * endIndex.
- *
- * One caveat: if the base iterator's begin and end indices change
- * the change will not be reflected by this wrapper. Does that matter?
- */
- // TODO: Review this class to see if it's still required.
- private static final class SafeCharIterator implements CharacterIterator,
- Cloneable {
-
- private CharacterIterator base;
- private int rangeStart;
- private int rangeLimit;
- private int currentIndex;
-
- SafeCharIterator(CharacterIterator base) {
- this.base = base;
- this.rangeStart = base.getBeginIndex();
- this.rangeLimit = base.getEndIndex();
- this.currentIndex = base.getIndex();
- }
-
- @Override
- public char first() {
- return setIndex(rangeStart);
- }
-
- @Override
- public char last() {
- return setIndex(rangeLimit - 1);
- }
-
- @Override
- public char current() {
- if (currentIndex < rangeStart || currentIndex >= rangeLimit) {
- return DONE;
- }
- else {
- return base.setIndex(currentIndex);
- }
- }
-
- @Override
- public char next() {
-
- currentIndex++;
- if (currentIndex >= rangeLimit) {
- currentIndex = rangeLimit;
- return DONE;
- }
- else {
- return base.setIndex(currentIndex);
- }
- }
-
- @Override
- public char previous() {
-
- currentIndex--;
- if (currentIndex < rangeStart) {
- currentIndex = rangeStart;
- return DONE;
- }
- else {
- return base.setIndex(currentIndex);
- }
- }
-
- @Override
- public char setIndex(int i) {
-
- if (i < rangeStart || i > rangeLimit) {
- throw new IllegalArgumentException("Invalid position");
- }
- currentIndex = i;
- return current();
- }
-
- @Override
- public int getBeginIndex() {
- return rangeStart;
- }
-
- @Override
- public int getEndIndex() {
- return rangeLimit;
- }
-
- @Override
- public int getIndex() {
- return currentIndex;
- }
-
- @Override
- public Object clone() {
-
- SafeCharIterator copy = null;
- try {
- copy = (SafeCharIterator) super.clone();
- }
- catch(CloneNotSupportedException e) {
- throw new Error("Clone not supported: " + e);
- }
-
- CharacterIterator copyOfBase = (CharacterIterator) base.clone();
- copy.base = copyOfBase;
- return copy;
- }
- }
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.util.resources;
+
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+/**
+ * BreakIteratorResourceBundle is an abstract class for loading BreakIterator
+ * data (rules or dictionary) from each module. An implementation class must
+ * implement getBreakIteratorInfo() that returns an instance of the
+ * corresponding BreakIteratorInfo (basename). The data name is taken from the
+ * BreakIteratorInfo instance.
+ *
+ * For example, if the given key is "WordDictionary" and Locale is "th", the
+ * data name is taken from a BreakIteratorInfo_th and the key's value is
+ * "thai_dict". Its data thai_dict is loaded from the Module of the
+ * implementation class of this class.
+ */
+
+public abstract class BreakIteratorResourceBundle extends ResourceBundle {
+ // If any keys that are not for data names are added to BreakIteratorInfo*,
+ // those keys must be added to NON_DATA_KEYS.
+ private static final Set NON_DATA_KEYS = Set.of("BreakIteratorClasses");
+
+ private volatile Set keys;
+
+ /**
+ * Returns an instance of the corresponding {@code BreakIteratorInfo} (basename).
+ * The instance shouldn't have its parent.
+ */
+ protected abstract ResourceBundle getBreakIteratorInfo();
+
+ @Override
+ protected Object handleGetObject(String key) {
+ if (NON_DATA_KEYS.contains(key)) {
+ return null;
+ }
+ ResourceBundle info = getBreakIteratorInfo();
+ if (!info.containsKey(key)) {
+ return null;
+ }
+ String path = getClass().getPackage().getName().replace('.', '/')
+ + '/' + info.getString(key);
+ byte[] data;
+ try (InputStream is = getResourceAsStream(path)) {
+ data = is.readAllBytes();
+ } catch (Exception e) {
+ throw new InternalError("Can't load " + path, e);
+ }
+ return data;
+ }
+
+ private InputStream getResourceAsStream(String path) throws Exception {
+ PrivilegedExceptionAction pa;
+ pa = () -> getClass().getModule().getResourceAsStream(path);
+ InputStream is;
+ try {
+ is = AccessController.doPrivileged(pa);
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ }
+ return is;
+ }
+
+ @Override
+ public Enumeration getKeys() {
+ return Collections.enumeration(keySet());
+ }
+
+ @Override
+ protected Set handleKeySet() {
+ if (keys == null) {
+ ResourceBundle info = getBreakIteratorInfo();
+ Set k = info.keySet();
+ k.removeAll(NON_DATA_KEYS);
+ synchronized (this) {
+ if (keys == null) {
+ keys = k;
+ }
+ }
+ }
+ return keys;
+ }
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java
--- a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java Fri Nov 11 16:44:36 2016 +0100
@@ -123,6 +123,14 @@
}
/**
+ * Gets a break iterator resources resource bundle, using
+ * privileges to allow accessing a sun.* package.
+ */
+ public ResourceBundle getBreakIteratorResources(Locale locale) {
+ return getBundle(type.getTextResourcesPackage() + ".BreakIteratorResources", locale);
+ }
+
+ /**
* Gets a collation data resource bundle, using privileges
* to allow accessing a sun.* package.
*/
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/conf/security/java.security
--- a/jdk/src/java.base/share/conf/security/java.security Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/conf/security/java.security Fri Nov 11 16:44:36 2016 +0100
@@ -645,6 +645,9 @@
# before larger keysize constraints of the same algorithm. For example:
# "RSA keySize < 1024 & jdkCA, RSA keySize < 2048".
#
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
# Note: This property is currently used by Oracle's PKIX implementation. It
# is not guaranteed to be examined and used by other implementations.
#
@@ -714,6 +717,9 @@
# See the specification of "jdk.certpath.disabledAlgorithms" for the
# syntax of the disabled algorithm string.
#
+# Note: The algorithm restrictions do not apply to trust anchors or
+# self-signed certificates.
+#
# Note: This property is currently used by Oracle's JSSE implementation.
# It is not guaranteed to be examined and used by other implementations.
#
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/lib/security/default.policy
--- a/jdk/src/java.base/share/lib/security/default.policy Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/lib/security/default.policy Fri Nov 11 16:44:36 2016 +0100
@@ -32,8 +32,22 @@
permission javax.smartcardio.CardPermission "*", "*";
permission java.lang.RuntimePermission "loadLibrary.j2pcsc";
permission java.lang.RuntimePermission
- "accessClassInPackage.sun.security.*";
- permission java.util.PropertyPermission "*", "read";
+ "accessClassInPackage.sun.security.jca";
+ permission java.lang.RuntimePermission
+ "accessClassInPackage.sun.security.util";
+ permission java.util.PropertyPermission
+ "javax.smartcardio.TerminalFactory.DefaultType", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "sun.arch.data.model", "read";
+ permission java.util.PropertyPermission
+ "sun.security.smartcardio.library", "read";
+ permission java.util.PropertyPermission
+ "sun.security.smartcardio.t0GetResponse", "read";
+ permission java.util.PropertyPermission
+ "sun.security.smartcardio.t1GetResponse", "read";
+ permission java.util.PropertyPermission
+ "sun.security.smartcardio.t1StripLe", "read";
// needed for looking up native PC/SC library
permission java.io.FilePermission "<>","read";
permission java.security.SecurityPermission "putProviderProperty.SunPCSC";
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/include/jvm.h
--- a/jdk/src/java.base/share/native/include/jvm.h Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/include/jvm.h Fri Nov 11 16:44:36 2016 +0100
@@ -165,14 +165,24 @@
JNIEXPORT jboolean JNICALL
JVM_IsSupportedJNIVersion(jint version);
+JNIEXPORT jobjectArray JNICALL
+JVM_GetVmArguments(JNIEnv *env);
+
+
/*
* java.lang.Throwable
*/
JNIEXPORT void JNICALL
JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
+/*
+ * java.lang.StackTraceElement
+ */
JNIEXPORT void JNICALL
-JVM_GetStackTraceElements(JNIEnv *env, jobject throwable, jobjectArray elements);
+JVM_InitStackTraceElementArray(JNIEnv *env, jobjectArray elements, jobject throwable);
+
+JNIEXPORT void JNICALL
+JVM_InitStackTraceElement(JNIEnv* env, jobject element, jobject stackFrameInfo);
/*
* java.lang.StackWalker
@@ -194,12 +204,6 @@
jint frame_count, jint start_index,
jobjectArray frames);
-JNIEXPORT void JNICALL
-JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
-
-JNIEXPORT jobjectArray JNICALL
-JVM_GetVmArguments(JNIEnv *env);
-
/*
* java.lang.Thread
*/
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/include/jvmti.h
--- a/jdk/src/java.base/share/native/include/jvmti.h Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2551 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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.
- */
-
- /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */
-
- /* Include file for the Java(tm) Virtual Machine Tool Interface */
-
-#ifndef _JAVA_JVMTI_H_
-#define _JAVA_JVMTI_H_
-
-#include "jni.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- JVMTI_VERSION_1 = 0x30010000,
- JVMTI_VERSION_1_0 = 0x30010000,
- JVMTI_VERSION_1_1 = 0x30010100,
- JVMTI_VERSION_1_2 = 0x30010200,
- JVMTI_VERSION_9 = 0x30090000,
-
- JVMTI_VERSION = 0x30000000 + (9 * 0x10000) + (0 * 0x100) + 0 /* version: 9.0.0 */
-};
-
-JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-
-JNIEXPORT jint JNICALL
-Agent_OnAttach(JavaVM* vm, char* options, void* reserved);
-
-JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm);
-
- /* Forward declaration of the environment */
-
-struct _jvmtiEnv;
-
-struct jvmtiInterface_1_;
-
-#ifdef __cplusplus
-typedef _jvmtiEnv jvmtiEnv;
-#else
-typedef const struct jvmtiInterface_1_ *jvmtiEnv;
-#endif /* __cplusplus */
-
-/* Derived Base Types */
-
-typedef jobject jthread;
-typedef jobject jthreadGroup;
-typedef jlong jlocation;
-struct _jrawMonitorID;
-typedef struct _jrawMonitorID *jrawMonitorID;
-typedef struct JNINativeInterface_ jniNativeInterface;
-
- /* Constants */
-
-
- /* Thread State Flags */
-
-enum {
- JVMTI_THREAD_STATE_ALIVE = 0x0001,
- JVMTI_THREAD_STATE_TERMINATED = 0x0002,
- JVMTI_THREAD_STATE_RUNNABLE = 0x0004,
- JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400,
- JVMTI_THREAD_STATE_WAITING = 0x0080,
- JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010,
- JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020,
- JVMTI_THREAD_STATE_SLEEPING = 0x0040,
- JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100,
- JVMTI_THREAD_STATE_PARKED = 0x0200,
- JVMTI_THREAD_STATE_SUSPENDED = 0x100000,
- JVMTI_THREAD_STATE_INTERRUPTED = 0x200000,
- JVMTI_THREAD_STATE_IN_NATIVE = 0x400000,
- JVMTI_THREAD_STATE_VENDOR_1 = 0x10000000,
- JVMTI_THREAD_STATE_VENDOR_2 = 0x20000000,
- JVMTI_THREAD_STATE_VENDOR_3 = 0x40000000
-};
-
- /* java.lang.Thread.State Conversion Masks */
-
-enum {
- JVMTI_JAVA_LANG_THREAD_STATE_MASK = JVMTI_THREAD_STATE_TERMINATED | JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT,
- JVMTI_JAVA_LANG_THREAD_STATE_NEW = 0,
- JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED = JVMTI_THREAD_STATE_TERMINATED,
- JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE,
- JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
- JVMTI_JAVA_LANG_THREAD_STATE_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_INDEFINITELY,
- JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
-};
-
- /* Thread Priority Constants */
-
-enum {
- JVMTI_THREAD_MIN_PRIORITY = 1,
- JVMTI_THREAD_NORM_PRIORITY = 5,
- JVMTI_THREAD_MAX_PRIORITY = 10
-};
-
- /* Heap Filter Flags */
-
-enum {
- JVMTI_HEAP_FILTER_TAGGED = 0x4,
- JVMTI_HEAP_FILTER_UNTAGGED = 0x8,
- JVMTI_HEAP_FILTER_CLASS_TAGGED = 0x10,
- JVMTI_HEAP_FILTER_CLASS_UNTAGGED = 0x20
-};
-
- /* Heap Visit Control Flags */
-
-enum {
- JVMTI_VISIT_OBJECTS = 0x100,
- JVMTI_VISIT_ABORT = 0x8000
-};
-
- /* Heap Reference Enumeration */
-
-typedef enum {
- JVMTI_HEAP_REFERENCE_CLASS = 1,
- JVMTI_HEAP_REFERENCE_FIELD = 2,
- JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT = 3,
- JVMTI_HEAP_REFERENCE_CLASS_LOADER = 4,
- JVMTI_HEAP_REFERENCE_SIGNERS = 5,
- JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN = 6,
- JVMTI_HEAP_REFERENCE_INTERFACE = 7,
- JVMTI_HEAP_REFERENCE_STATIC_FIELD = 8,
- JVMTI_HEAP_REFERENCE_CONSTANT_POOL = 9,
- JVMTI_HEAP_REFERENCE_SUPERCLASS = 10,
- JVMTI_HEAP_REFERENCE_JNI_GLOBAL = 21,
- JVMTI_HEAP_REFERENCE_SYSTEM_CLASS = 22,
- JVMTI_HEAP_REFERENCE_MONITOR = 23,
- JVMTI_HEAP_REFERENCE_STACK_LOCAL = 24,
- JVMTI_HEAP_REFERENCE_JNI_LOCAL = 25,
- JVMTI_HEAP_REFERENCE_THREAD = 26,
- JVMTI_HEAP_REFERENCE_OTHER = 27
-} jvmtiHeapReferenceKind;
-
- /* Primitive Type Enumeration */
-
-typedef enum {
- JVMTI_PRIMITIVE_TYPE_BOOLEAN = 90,
- JVMTI_PRIMITIVE_TYPE_BYTE = 66,
- JVMTI_PRIMITIVE_TYPE_CHAR = 67,
- JVMTI_PRIMITIVE_TYPE_SHORT = 83,
- JVMTI_PRIMITIVE_TYPE_INT = 73,
- JVMTI_PRIMITIVE_TYPE_LONG = 74,
- JVMTI_PRIMITIVE_TYPE_FLOAT = 70,
- JVMTI_PRIMITIVE_TYPE_DOUBLE = 68
-} jvmtiPrimitiveType;
-
- /* Heap Object Filter Enumeration */
-
-typedef enum {
- JVMTI_HEAP_OBJECT_TAGGED = 1,
- JVMTI_HEAP_OBJECT_UNTAGGED = 2,
- JVMTI_HEAP_OBJECT_EITHER = 3
-} jvmtiHeapObjectFilter;
-
- /* Heap Root Kind Enumeration */
-
-typedef enum {
- JVMTI_HEAP_ROOT_JNI_GLOBAL = 1,
- JVMTI_HEAP_ROOT_SYSTEM_CLASS = 2,
- JVMTI_HEAP_ROOT_MONITOR = 3,
- JVMTI_HEAP_ROOT_STACK_LOCAL = 4,
- JVMTI_HEAP_ROOT_JNI_LOCAL = 5,
- JVMTI_HEAP_ROOT_THREAD = 6,
- JVMTI_HEAP_ROOT_OTHER = 7
-} jvmtiHeapRootKind;
-
- /* Object Reference Enumeration */
-
-typedef enum {
- JVMTI_REFERENCE_CLASS = 1,
- JVMTI_REFERENCE_FIELD = 2,
- JVMTI_REFERENCE_ARRAY_ELEMENT = 3,
- JVMTI_REFERENCE_CLASS_LOADER = 4,
- JVMTI_REFERENCE_SIGNERS = 5,
- JVMTI_REFERENCE_PROTECTION_DOMAIN = 6,
- JVMTI_REFERENCE_INTERFACE = 7,
- JVMTI_REFERENCE_STATIC_FIELD = 8,
- JVMTI_REFERENCE_CONSTANT_POOL = 9
-} jvmtiObjectReferenceKind;
-
- /* Iteration Control Enumeration */
-
-typedef enum {
- JVMTI_ITERATION_CONTINUE = 1,
- JVMTI_ITERATION_IGNORE = 2,
- JVMTI_ITERATION_ABORT = 0
-} jvmtiIterationControl;
-
- /* Class Status Flags */
-
-enum {
- JVMTI_CLASS_STATUS_VERIFIED = 1,
- JVMTI_CLASS_STATUS_PREPARED = 2,
- JVMTI_CLASS_STATUS_INITIALIZED = 4,
- JVMTI_CLASS_STATUS_ERROR = 8,
- JVMTI_CLASS_STATUS_ARRAY = 16,
- JVMTI_CLASS_STATUS_PRIMITIVE = 32
-};
-
- /* Event Enable/Disable */
-
-typedef enum {
- JVMTI_ENABLE = 1,
- JVMTI_DISABLE = 0
-} jvmtiEventMode;
-
- /* Extension Function/Event Parameter Types */
-
-typedef enum {
- JVMTI_TYPE_JBYTE = 101,
- JVMTI_TYPE_JCHAR = 102,
- JVMTI_TYPE_JSHORT = 103,
- JVMTI_TYPE_JINT = 104,
- JVMTI_TYPE_JLONG = 105,
- JVMTI_TYPE_JFLOAT = 106,
- JVMTI_TYPE_JDOUBLE = 107,
- JVMTI_TYPE_JBOOLEAN = 108,
- JVMTI_TYPE_JOBJECT = 109,
- JVMTI_TYPE_JTHREAD = 110,
- JVMTI_TYPE_JCLASS = 111,
- JVMTI_TYPE_JVALUE = 112,
- JVMTI_TYPE_JFIELDID = 113,
- JVMTI_TYPE_JMETHODID = 114,
- JVMTI_TYPE_CCHAR = 115,
- JVMTI_TYPE_CVOID = 116,
- JVMTI_TYPE_JNIENV = 117
-} jvmtiParamTypes;
-
- /* Extension Function/Event Parameter Kinds */
-
-typedef enum {
- JVMTI_KIND_IN = 91,
- JVMTI_KIND_IN_PTR = 92,
- JVMTI_KIND_IN_BUF = 93,
- JVMTI_KIND_ALLOC_BUF = 94,
- JVMTI_KIND_ALLOC_ALLOC_BUF = 95,
- JVMTI_KIND_OUT = 96,
- JVMTI_KIND_OUT_BUF = 97
-} jvmtiParamKind;
-
- /* Timer Kinds */
-
-typedef enum {
- JVMTI_TIMER_USER_CPU = 30,
- JVMTI_TIMER_TOTAL_CPU = 31,
- JVMTI_TIMER_ELAPSED = 32
-} jvmtiTimerKind;
-
- /* Phases of execution */
-
-typedef enum {
- JVMTI_PHASE_ONLOAD = 1,
- JVMTI_PHASE_PRIMORDIAL = 2,
- JVMTI_PHASE_START = 6,
- JVMTI_PHASE_LIVE = 4,
- JVMTI_PHASE_DEAD = 8
-} jvmtiPhase;
-
- /* Version Interface Types */
-
-enum {
- JVMTI_VERSION_INTERFACE_JNI = 0x00000000,
- JVMTI_VERSION_INTERFACE_JVMTI = 0x30000000
-};
-
- /* Version Masks */
-
-enum {
- JVMTI_VERSION_MASK_INTERFACE_TYPE = 0x70000000,
- JVMTI_VERSION_MASK_MAJOR = 0x0FFF0000,
- JVMTI_VERSION_MASK_MINOR = 0x0000FF00,
- JVMTI_VERSION_MASK_MICRO = 0x000000FF
-};
-
- /* Version Shifts */
-
-enum {
- JVMTI_VERSION_SHIFT_MAJOR = 16,
- JVMTI_VERSION_SHIFT_MINOR = 8,
- JVMTI_VERSION_SHIFT_MICRO = 0
-};
-
- /* Verbose Flag Enumeration */
-
-typedef enum {
- JVMTI_VERBOSE_OTHER = 0,
- JVMTI_VERBOSE_GC = 1,
- JVMTI_VERBOSE_CLASS = 2,
- JVMTI_VERBOSE_JNI = 4
-} jvmtiVerboseFlag;
-
- /* JLocation Format Enumeration */
-
-typedef enum {
- JVMTI_JLOCATION_JVMBCI = 1,
- JVMTI_JLOCATION_MACHINEPC = 2,
- JVMTI_JLOCATION_OTHER = 0
-} jvmtiJlocationFormat;
-
- /* Resource Exhaustion Flags */
-
-enum {
- JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR = 0x0001,
- JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP = 0x0002,
- JVMTI_RESOURCE_EXHAUSTED_THREADS = 0x0004
-};
-
- /* Errors */
-
-typedef enum {
- JVMTI_ERROR_NONE = 0,
- JVMTI_ERROR_INVALID_THREAD = 10,
- JVMTI_ERROR_INVALID_THREAD_GROUP = 11,
- JVMTI_ERROR_INVALID_PRIORITY = 12,
- JVMTI_ERROR_THREAD_NOT_SUSPENDED = 13,
- JVMTI_ERROR_THREAD_SUSPENDED = 14,
- JVMTI_ERROR_THREAD_NOT_ALIVE = 15,
- JVMTI_ERROR_INVALID_OBJECT = 20,
- JVMTI_ERROR_INVALID_CLASS = 21,
- JVMTI_ERROR_CLASS_NOT_PREPARED = 22,
- JVMTI_ERROR_INVALID_METHODID = 23,
- JVMTI_ERROR_INVALID_LOCATION = 24,
- JVMTI_ERROR_INVALID_FIELDID = 25,
- JVMTI_ERROR_NO_MORE_FRAMES = 31,
- JVMTI_ERROR_OPAQUE_FRAME = 32,
- JVMTI_ERROR_TYPE_MISMATCH = 34,
- JVMTI_ERROR_INVALID_SLOT = 35,
- JVMTI_ERROR_DUPLICATE = 40,
- JVMTI_ERROR_NOT_FOUND = 41,
- JVMTI_ERROR_INVALID_MONITOR = 50,
- JVMTI_ERROR_NOT_MONITOR_OWNER = 51,
- JVMTI_ERROR_INTERRUPT = 52,
- JVMTI_ERROR_INVALID_CLASS_FORMAT = 60,
- JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION = 61,
- JVMTI_ERROR_FAILS_VERIFICATION = 62,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED = 63,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED = 64,
- JVMTI_ERROR_INVALID_TYPESTATE = 65,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED = 66,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED = 67,
- JVMTI_ERROR_UNSUPPORTED_VERSION = 68,
- JVMTI_ERROR_NAMES_DONT_MATCH = 69,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70,
- JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71,
- JVMTI_ERROR_UNMODIFIABLE_CLASS = 79,
- JVMTI_ERROR_NOT_AVAILABLE = 98,
- JVMTI_ERROR_MUST_POSSESS_CAPABILITY = 99,
- JVMTI_ERROR_NULL_POINTER = 100,
- JVMTI_ERROR_ABSENT_INFORMATION = 101,
- JVMTI_ERROR_INVALID_EVENT_TYPE = 102,
- JVMTI_ERROR_ILLEGAL_ARGUMENT = 103,
- JVMTI_ERROR_NATIVE_METHOD = 104,
- JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED = 106,
- JVMTI_ERROR_OUT_OF_MEMORY = 110,
- JVMTI_ERROR_ACCESS_DENIED = 111,
- JVMTI_ERROR_WRONG_PHASE = 112,
- JVMTI_ERROR_INTERNAL = 113,
- JVMTI_ERROR_UNATTACHED_THREAD = 115,
- JVMTI_ERROR_INVALID_ENVIRONMENT = 116,
- JVMTI_ERROR_MAX = 116
-} jvmtiError;
-
- /* Event IDs */
-
-typedef enum {
- JVMTI_MIN_EVENT_TYPE_VAL = 50,
- JVMTI_EVENT_VM_INIT = 50,
- JVMTI_EVENT_VM_DEATH = 51,
- JVMTI_EVENT_THREAD_START = 52,
- JVMTI_EVENT_THREAD_END = 53,
- JVMTI_EVENT_CLASS_FILE_LOAD_HOOK = 54,
- JVMTI_EVENT_CLASS_LOAD = 55,
- JVMTI_EVENT_CLASS_PREPARE = 56,
- JVMTI_EVENT_VM_START = 57,
- JVMTI_EVENT_EXCEPTION = 58,
- JVMTI_EVENT_EXCEPTION_CATCH = 59,
- JVMTI_EVENT_SINGLE_STEP = 60,
- JVMTI_EVENT_FRAME_POP = 61,
- JVMTI_EVENT_BREAKPOINT = 62,
- JVMTI_EVENT_FIELD_ACCESS = 63,
- JVMTI_EVENT_FIELD_MODIFICATION = 64,
- JVMTI_EVENT_METHOD_ENTRY = 65,
- JVMTI_EVENT_METHOD_EXIT = 66,
- JVMTI_EVENT_NATIVE_METHOD_BIND = 67,
- JVMTI_EVENT_COMPILED_METHOD_LOAD = 68,
- JVMTI_EVENT_COMPILED_METHOD_UNLOAD = 69,
- JVMTI_EVENT_DYNAMIC_CODE_GENERATED = 70,
- JVMTI_EVENT_DATA_DUMP_REQUEST = 71,
- JVMTI_EVENT_MONITOR_WAIT = 73,
- JVMTI_EVENT_MONITOR_WAITED = 74,
- JVMTI_EVENT_MONITOR_CONTENDED_ENTER = 75,
- JVMTI_EVENT_MONITOR_CONTENDED_ENTERED = 76,
- JVMTI_EVENT_RESOURCE_EXHAUSTED = 80,
- JVMTI_EVENT_GARBAGE_COLLECTION_START = 81,
- JVMTI_EVENT_GARBAGE_COLLECTION_FINISH = 82,
- JVMTI_EVENT_OBJECT_FREE = 83,
- JVMTI_EVENT_VM_OBJECT_ALLOC = 84,
- JVMTI_MAX_EVENT_TYPE_VAL = 84
-} jvmtiEvent;
-
-
- /* Pre-Declarations */
-struct _jvmtiThreadInfo;
-typedef struct _jvmtiThreadInfo jvmtiThreadInfo;
-struct _jvmtiMonitorStackDepthInfo;
-typedef struct _jvmtiMonitorStackDepthInfo jvmtiMonitorStackDepthInfo;
-struct _jvmtiThreadGroupInfo;
-typedef struct _jvmtiThreadGroupInfo jvmtiThreadGroupInfo;
-struct _jvmtiFrameInfo;
-typedef struct _jvmtiFrameInfo jvmtiFrameInfo;
-struct _jvmtiStackInfo;
-typedef struct _jvmtiStackInfo jvmtiStackInfo;
-struct _jvmtiHeapReferenceInfoField;
-typedef struct _jvmtiHeapReferenceInfoField jvmtiHeapReferenceInfoField;
-struct _jvmtiHeapReferenceInfoArray;
-typedef struct _jvmtiHeapReferenceInfoArray jvmtiHeapReferenceInfoArray;
-struct _jvmtiHeapReferenceInfoConstantPool;
-typedef struct _jvmtiHeapReferenceInfoConstantPool jvmtiHeapReferenceInfoConstantPool;
-struct _jvmtiHeapReferenceInfoStackLocal;
-typedef struct _jvmtiHeapReferenceInfoStackLocal jvmtiHeapReferenceInfoStackLocal;
-struct _jvmtiHeapReferenceInfoJniLocal;
-typedef struct _jvmtiHeapReferenceInfoJniLocal jvmtiHeapReferenceInfoJniLocal;
-struct _jvmtiHeapReferenceInfoReserved;
-typedef struct _jvmtiHeapReferenceInfoReserved jvmtiHeapReferenceInfoReserved;
-union _jvmtiHeapReferenceInfo;
-typedef union _jvmtiHeapReferenceInfo jvmtiHeapReferenceInfo;
-struct _jvmtiHeapCallbacks;
-typedef struct _jvmtiHeapCallbacks jvmtiHeapCallbacks;
-struct _jvmtiClassDefinition;
-typedef struct _jvmtiClassDefinition jvmtiClassDefinition;
-struct _jvmtiMonitorUsage;
-typedef struct _jvmtiMonitorUsage jvmtiMonitorUsage;
-struct _jvmtiLineNumberEntry;
-typedef struct _jvmtiLineNumberEntry jvmtiLineNumberEntry;
-struct _jvmtiLocalVariableEntry;
-typedef struct _jvmtiLocalVariableEntry jvmtiLocalVariableEntry;
-struct _jvmtiParamInfo;
-typedef struct _jvmtiParamInfo jvmtiParamInfo;
-struct _jvmtiExtensionFunctionInfo;
-typedef struct _jvmtiExtensionFunctionInfo jvmtiExtensionFunctionInfo;
-struct _jvmtiExtensionEventInfo;
-typedef struct _jvmtiExtensionEventInfo jvmtiExtensionEventInfo;
-struct _jvmtiTimerInfo;
-typedef struct _jvmtiTimerInfo jvmtiTimerInfo;
-struct _jvmtiAddrLocationMap;
-typedef struct _jvmtiAddrLocationMap jvmtiAddrLocationMap;
-
- /* Function Types */
-
-typedef void (JNICALL *jvmtiStartFunction)
- (jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg);
-
-typedef jint (JNICALL *jvmtiHeapIterationCallback)
- (jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data);
-
-typedef jint (JNICALL *jvmtiHeapReferenceCallback)
- (jvmtiHeapReferenceKind reference_kind, const jvmtiHeapReferenceInfo* reference_info, jlong class_tag, jlong referrer_class_tag, jlong size, jlong* tag_ptr, jlong* referrer_tag_ptr, jint length, void* user_data);
-
-typedef jint (JNICALL *jvmtiPrimitiveFieldCallback)
- (jvmtiHeapReferenceKind kind, const jvmtiHeapReferenceInfo* info, jlong object_class_tag, jlong* object_tag_ptr, jvalue value, jvmtiPrimitiveType value_type, void* user_data);
-
-typedef jint (JNICALL *jvmtiArrayPrimitiveValueCallback)
- (jlong class_tag, jlong size, jlong* tag_ptr, jint element_count, jvmtiPrimitiveType element_type, const void* elements, void* user_data);
-
-typedef jint (JNICALL *jvmtiStringPrimitiveValueCallback)
- (jlong class_tag, jlong size, jlong* tag_ptr, const jchar* value, jint value_length, void* user_data);
-
-typedef jint (JNICALL *jvmtiReservedCallback)
- ();
-
-typedef jvmtiIterationControl (JNICALL *jvmtiHeapObjectCallback)
- (jlong class_tag, jlong size, jlong* tag_ptr, void* user_data);
-
-typedef jvmtiIterationControl (JNICALL *jvmtiHeapRootCallback)
- (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, void* user_data);
-
-typedef jvmtiIterationControl (JNICALL *jvmtiStackReferenceCallback)
- (jvmtiHeapRootKind root_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong thread_tag, jint depth, jmethodID method, jint slot, void* user_data);
-
-typedef jvmtiIterationControl (JNICALL *jvmtiObjectReferenceCallback)
- (jvmtiObjectReferenceKind reference_kind, jlong class_tag, jlong size, jlong* tag_ptr, jlong referrer_tag, jint referrer_index, void* user_data);
-
-typedef jvmtiError (JNICALL *jvmtiExtensionFunction)
- (jvmtiEnv* jvmti_env, ...);
-
-typedef void (JNICALL *jvmtiExtensionEvent)
- (jvmtiEnv* jvmti_env, ...);
-
-
- /* Structure Types */
-struct _jvmtiThreadInfo {
- char* name;
- jint priority;
- jboolean is_daemon;
- jthreadGroup thread_group;
- jobject context_class_loader;
-};
-struct _jvmtiMonitorStackDepthInfo {
- jobject monitor;
- jint stack_depth;
-};
-struct _jvmtiThreadGroupInfo {
- jthreadGroup parent;
- char* name;
- jint max_priority;
- jboolean is_daemon;
-};
-struct _jvmtiFrameInfo {
- jmethodID method;
- jlocation location;
-};
-struct _jvmtiStackInfo {
- jthread thread;
- jint state;
- jvmtiFrameInfo* frame_buffer;
- jint frame_count;
-};
-struct _jvmtiHeapReferenceInfoField {
- jint index;
-};
-struct _jvmtiHeapReferenceInfoArray {
- jint index;
-};
-struct _jvmtiHeapReferenceInfoConstantPool {
- jint index;
-};
-struct _jvmtiHeapReferenceInfoStackLocal {
- jlong thread_tag;
- jlong thread_id;
- jint depth;
- jmethodID method;
- jlocation location;
- jint slot;
-};
-struct _jvmtiHeapReferenceInfoJniLocal {
- jlong thread_tag;
- jlong thread_id;
- jint depth;
- jmethodID method;
-};
-struct _jvmtiHeapReferenceInfoReserved {
- jlong reserved1;
- jlong reserved2;
- jlong reserved3;
- jlong reserved4;
- jlong reserved5;
- jlong reserved6;
- jlong reserved7;
- jlong reserved8;
-};
-union _jvmtiHeapReferenceInfo {
- jvmtiHeapReferenceInfoField field;
- jvmtiHeapReferenceInfoArray array;
- jvmtiHeapReferenceInfoConstantPool constant_pool;
- jvmtiHeapReferenceInfoStackLocal stack_local;
- jvmtiHeapReferenceInfoJniLocal jni_local;
- jvmtiHeapReferenceInfoReserved other;
-};
-struct _jvmtiHeapCallbacks {
- jvmtiHeapIterationCallback heap_iteration_callback;
- jvmtiHeapReferenceCallback heap_reference_callback;
- jvmtiPrimitiveFieldCallback primitive_field_callback;
- jvmtiArrayPrimitiveValueCallback array_primitive_value_callback;
- jvmtiStringPrimitiveValueCallback string_primitive_value_callback;
- jvmtiReservedCallback reserved5;
- jvmtiReservedCallback reserved6;
- jvmtiReservedCallback reserved7;
- jvmtiReservedCallback reserved8;
- jvmtiReservedCallback reserved9;
- jvmtiReservedCallback reserved10;
- jvmtiReservedCallback reserved11;
- jvmtiReservedCallback reserved12;
- jvmtiReservedCallback reserved13;
- jvmtiReservedCallback reserved14;
- jvmtiReservedCallback reserved15;
-};
-struct _jvmtiClassDefinition {
- jclass klass;
- jint class_byte_count;
- const unsigned char* class_bytes;
-};
-struct _jvmtiMonitorUsage {
- jthread owner;
- jint entry_count;
- jint waiter_count;
- jthread* waiters;
- jint notify_waiter_count;
- jthread* notify_waiters;
-};
-struct _jvmtiLineNumberEntry {
- jlocation start_location;
- jint line_number;
-};
-struct _jvmtiLocalVariableEntry {
- jlocation start_location;
- jint length;
- char* name;
- char* signature;
- char* generic_signature;
- jint slot;
-};
-struct _jvmtiParamInfo {
- char* name;
- jvmtiParamKind kind;
- jvmtiParamTypes base_type;
- jboolean null_ok;
-};
-struct _jvmtiExtensionFunctionInfo {
- jvmtiExtensionFunction func;
- char* id;
- char* short_description;
- jint param_count;
- jvmtiParamInfo* params;
- jint error_count;
- jvmtiError* errors;
-};
-struct _jvmtiExtensionEventInfo {
- jint extension_event_index;
- char* id;
- char* short_description;
- jint param_count;
- jvmtiParamInfo* params;
-};
-struct _jvmtiTimerInfo {
- jlong max_value;
- jboolean may_skip_forward;
- jboolean may_skip_backward;
- jvmtiTimerKind kind;
- jlong reserved1;
- jlong reserved2;
-};
-struct _jvmtiAddrLocationMap {
- const void* start_address;
- jlocation location;
-};
-
-typedef struct {
- unsigned int can_tag_objects : 1;
- unsigned int can_generate_field_modification_events : 1;
- unsigned int can_generate_field_access_events : 1;
- unsigned int can_get_bytecodes : 1;
- unsigned int can_get_synthetic_attribute : 1;
- unsigned int can_get_owned_monitor_info : 1;
- unsigned int can_get_current_contended_monitor : 1;
- unsigned int can_get_monitor_info : 1;
- unsigned int can_pop_frame : 1;
- unsigned int can_redefine_classes : 1;
- unsigned int can_signal_thread : 1;
- unsigned int can_get_source_file_name : 1;
- unsigned int can_get_line_numbers : 1;
- unsigned int can_get_source_debug_extension : 1;
- unsigned int can_access_local_variables : 1;
- unsigned int can_maintain_original_method_order : 1;
- unsigned int can_generate_single_step_events : 1;
- unsigned int can_generate_exception_events : 1;
- unsigned int can_generate_frame_pop_events : 1;
- unsigned int can_generate_breakpoint_events : 1;
- unsigned int can_suspend : 1;
- unsigned int can_redefine_any_class : 1;
- unsigned int can_get_current_thread_cpu_time : 1;
- unsigned int can_get_thread_cpu_time : 1;
- unsigned int can_generate_method_entry_events : 1;
- unsigned int can_generate_method_exit_events : 1;
- unsigned int can_generate_all_class_hook_events : 1;
- unsigned int can_generate_compiled_method_load_events : 1;
- unsigned int can_generate_monitor_events : 1;
- unsigned int can_generate_vm_object_alloc_events : 1;
- unsigned int can_generate_native_method_bind_events : 1;
- unsigned int can_generate_garbage_collection_events : 1;
- unsigned int can_generate_object_free_events : 1;
- unsigned int can_force_early_return : 1;
- unsigned int can_get_owned_monitor_stack_depth_info : 1;
- unsigned int can_get_constant_pool : 1;
- unsigned int can_set_native_method_prefix : 1;
- unsigned int can_retransform_classes : 1;
- unsigned int can_retransform_any_class : 1;
- unsigned int can_generate_resource_exhaustion_heap_events : 1;
- unsigned int can_generate_resource_exhaustion_threads_events : 1;
- unsigned int can_generate_early_vmstart : 1;
- unsigned int can_generate_early_class_hook_events : 1;
- unsigned int : 5;
- unsigned int : 16;
- unsigned int : 16;
- unsigned int : 16;
- unsigned int : 16;
- unsigned int : 16;
-} jvmtiCapabilities;
-
-
- /* Event Definitions */
-
-typedef void (JNICALL *jvmtiEventReserved)(void);
-
-
-typedef void (JNICALL *jvmtiEventBreakpoint)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location);
-
-typedef void (JNICALL *jvmtiEventClassFileLoadHook)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jclass class_being_redefined,
- jobject loader,
- const char* name,
- jobject protection_domain,
- jint class_data_len,
- const unsigned char* class_data,
- jint* new_class_data_len,
- unsigned char** new_class_data);
-
-typedef void (JNICALL *jvmtiEventClassLoad)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jclass klass);
-
-typedef void (JNICALL *jvmtiEventClassPrepare)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jclass klass);
-
-typedef void (JNICALL *jvmtiEventCompiledMethodLoad)
- (jvmtiEnv *jvmti_env,
- jmethodID method,
- jint code_size,
- const void* code_addr,
- jint map_length,
- const jvmtiAddrLocationMap* map,
- const void* compile_info);
-
-typedef void (JNICALL *jvmtiEventCompiledMethodUnload)
- (jvmtiEnv *jvmti_env,
- jmethodID method,
- const void* code_addr);
-
-typedef void (JNICALL *jvmtiEventDataDumpRequest)
- (jvmtiEnv *jvmti_env);
-
-typedef void (JNICALL *jvmtiEventDynamicCodeGenerated)
- (jvmtiEnv *jvmti_env,
- const char* name,
- const void* address,
- jint length);
-
-typedef void (JNICALL *jvmtiEventException)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location,
- jobject exception,
- jmethodID catch_method,
- jlocation catch_location);
-
-typedef void (JNICALL *jvmtiEventExceptionCatch)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location,
- jobject exception);
-
-typedef void (JNICALL *jvmtiEventFieldAccess)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location,
- jclass field_klass,
- jobject object,
- jfieldID field);
-
-typedef void (JNICALL *jvmtiEventFieldModification)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location,
- jclass field_klass,
- jobject object,
- jfieldID field,
- char signature_type,
- jvalue new_value);
-
-typedef void (JNICALL *jvmtiEventFramePop)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jboolean was_popped_by_exception);
-
-typedef void (JNICALL *jvmtiEventGarbageCollectionFinish)
- (jvmtiEnv *jvmti_env);
-
-typedef void (JNICALL *jvmtiEventGarbageCollectionStart)
- (jvmtiEnv *jvmti_env);
-
-typedef void (JNICALL *jvmtiEventMethodEntry)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method);
-
-typedef void (JNICALL *jvmtiEventMethodExit)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jboolean was_popped_by_exception,
- jvalue return_value);
-
-typedef void (JNICALL *jvmtiEventMonitorContendedEnter)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jobject object);
-
-typedef void (JNICALL *jvmtiEventMonitorContendedEntered)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jobject object);
-
-typedef void (JNICALL *jvmtiEventMonitorWait)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jobject object,
- jlong timeout);
-
-typedef void (JNICALL *jvmtiEventMonitorWaited)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jobject object,
- jboolean timed_out);
-
-typedef void (JNICALL *jvmtiEventNativeMethodBind)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- void* address,
- void** new_address_ptr);
-
-typedef void (JNICALL *jvmtiEventObjectFree)
- (jvmtiEnv *jvmti_env,
- jlong tag);
-
-typedef void (JNICALL *jvmtiEventResourceExhausted)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jint flags,
- const void* reserved,
- const char* description);
-
-typedef void (JNICALL *jvmtiEventSingleStep)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jmethodID method,
- jlocation location);
-
-typedef void (JNICALL *jvmtiEventThreadEnd)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread);
-
-typedef void (JNICALL *jvmtiEventThreadStart)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread);
-
-typedef void (JNICALL *jvmtiEventVMDeath)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env);
-
-typedef void (JNICALL *jvmtiEventVMInit)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread);
-
-typedef void (JNICALL *jvmtiEventVMObjectAlloc)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env,
- jthread thread,
- jobject object,
- jclass object_klass,
- jlong size);
-
-typedef void (JNICALL *jvmtiEventVMStart)
- (jvmtiEnv *jvmti_env,
- JNIEnv* jni_env);
-
- /* Event Callback Structure */
-
-typedef struct {
- /* 50 : VM Initialization Event */
- jvmtiEventVMInit VMInit;
- /* 51 : VM Death Event */
- jvmtiEventVMDeath VMDeath;
- /* 52 : Thread Start */
- jvmtiEventThreadStart ThreadStart;
- /* 53 : Thread End */
- jvmtiEventThreadEnd ThreadEnd;
- /* 54 : Class File Load Hook */
- jvmtiEventClassFileLoadHook ClassFileLoadHook;
- /* 55 : Class Load */
- jvmtiEventClassLoad ClassLoad;
- /* 56 : Class Prepare */
- jvmtiEventClassPrepare ClassPrepare;
- /* 57 : VM Start Event */
- jvmtiEventVMStart VMStart;
- /* 58 : Exception */
- jvmtiEventException Exception;
- /* 59 : Exception Catch */
- jvmtiEventExceptionCatch ExceptionCatch;
- /* 60 : Single Step */
- jvmtiEventSingleStep SingleStep;
- /* 61 : Frame Pop */
- jvmtiEventFramePop FramePop;
- /* 62 : Breakpoint */
- jvmtiEventBreakpoint Breakpoint;
- /* 63 : Field Access */
- jvmtiEventFieldAccess FieldAccess;
- /* 64 : Field Modification */
- jvmtiEventFieldModification FieldModification;
- /* 65 : Method Entry */
- jvmtiEventMethodEntry MethodEntry;
- /* 66 : Method Exit */
- jvmtiEventMethodExit MethodExit;
- /* 67 : Native Method Bind */
- jvmtiEventNativeMethodBind NativeMethodBind;
- /* 68 : Compiled Method Load */
- jvmtiEventCompiledMethodLoad CompiledMethodLoad;
- /* 69 : Compiled Method Unload */
- jvmtiEventCompiledMethodUnload CompiledMethodUnload;
- /* 70 : Dynamic Code Generated */
- jvmtiEventDynamicCodeGenerated DynamicCodeGenerated;
- /* 71 : Data Dump Request */
- jvmtiEventDataDumpRequest DataDumpRequest;
- /* 72 */
- jvmtiEventReserved reserved72;
- /* 73 : Monitor Wait */
- jvmtiEventMonitorWait MonitorWait;
- /* 74 : Monitor Waited */
- jvmtiEventMonitorWaited MonitorWaited;
- /* 75 : Monitor Contended Enter */
- jvmtiEventMonitorContendedEnter MonitorContendedEnter;
- /* 76 : Monitor Contended Entered */
- jvmtiEventMonitorContendedEntered MonitorContendedEntered;
- /* 77 */
- jvmtiEventReserved reserved77;
- /* 78 */
- jvmtiEventReserved reserved78;
- /* 79 */
- jvmtiEventReserved reserved79;
- /* 80 : Resource Exhausted */
- jvmtiEventResourceExhausted ResourceExhausted;
- /* 81 : Garbage Collection Start */
- jvmtiEventGarbageCollectionStart GarbageCollectionStart;
- /* 82 : Garbage Collection Finish */
- jvmtiEventGarbageCollectionFinish GarbageCollectionFinish;
- /* 83 : Object Free */
- jvmtiEventObjectFree ObjectFree;
- /* 84 : VM Object Allocation */
- jvmtiEventVMObjectAlloc VMObjectAlloc;
-} jvmtiEventCallbacks;
-
-
- /* Function Interface */
-
-typedef struct jvmtiInterface_1_ {
-
- /* 1 : RESERVED */
- void *reserved1;
-
- /* 2 : Set Event Notification Mode */
- jvmtiError (JNICALL *SetEventNotificationMode) (jvmtiEnv* env,
- jvmtiEventMode mode,
- jvmtiEvent event_type,
- jthread event_thread,
- ...);
-
- /* 3 : Get All Modules */
- jvmtiError (JNICALL *GetAllModules) (jvmtiEnv* env,
- jint* module_count_ptr,
- jobject** modules_ptr);
-
- /* 4 : Get All Threads */
- jvmtiError (JNICALL *GetAllThreads) (jvmtiEnv* env,
- jint* threads_count_ptr,
- jthread** threads_ptr);
-
- /* 5 : Suspend Thread */
- jvmtiError (JNICALL *SuspendThread) (jvmtiEnv* env,
- jthread thread);
-
- /* 6 : Resume Thread */
- jvmtiError (JNICALL *ResumeThread) (jvmtiEnv* env,
- jthread thread);
-
- /* 7 : Stop Thread */
- jvmtiError (JNICALL *StopThread) (jvmtiEnv* env,
- jthread thread,
- jobject exception);
-
- /* 8 : Interrupt Thread */
- jvmtiError (JNICALL *InterruptThread) (jvmtiEnv* env,
- jthread thread);
-
- /* 9 : Get Thread Info */
- jvmtiError (JNICALL *GetThreadInfo) (jvmtiEnv* env,
- jthread thread,
- jvmtiThreadInfo* info_ptr);
-
- /* 10 : Get Owned Monitor Info */
- jvmtiError (JNICALL *GetOwnedMonitorInfo) (jvmtiEnv* env,
- jthread thread,
- jint* owned_monitor_count_ptr,
- jobject** owned_monitors_ptr);
-
- /* 11 : Get Current Contended Monitor */
- jvmtiError (JNICALL *GetCurrentContendedMonitor) (jvmtiEnv* env,
- jthread thread,
- jobject* monitor_ptr);
-
- /* 12 : Run Agent Thread */
- jvmtiError (JNICALL *RunAgentThread) (jvmtiEnv* env,
- jthread thread,
- jvmtiStartFunction proc,
- const void* arg,
- jint priority);
-
- /* 13 : Get Top Thread Groups */
- jvmtiError (JNICALL *GetTopThreadGroups) (jvmtiEnv* env,
- jint* group_count_ptr,
- jthreadGroup** groups_ptr);
-
- /* 14 : Get Thread Group Info */
- jvmtiError (JNICALL *GetThreadGroupInfo) (jvmtiEnv* env,
- jthreadGroup group,
- jvmtiThreadGroupInfo* info_ptr);
-
- /* 15 : Get Thread Group Children */
- jvmtiError (JNICALL *GetThreadGroupChildren) (jvmtiEnv* env,
- jthreadGroup group,
- jint* thread_count_ptr,
- jthread** threads_ptr,
- jint* group_count_ptr,
- jthreadGroup** groups_ptr);
-
- /* 16 : Get Frame Count */
- jvmtiError (JNICALL *GetFrameCount) (jvmtiEnv* env,
- jthread thread,
- jint* count_ptr);
-
- /* 17 : Get Thread State */
- jvmtiError (JNICALL *GetThreadState) (jvmtiEnv* env,
- jthread thread,
- jint* thread_state_ptr);
-
- /* 18 : Get Current Thread */
- jvmtiError (JNICALL *GetCurrentThread) (jvmtiEnv* env,
- jthread* thread_ptr);
-
- /* 19 : Get Frame Location */
- jvmtiError (JNICALL *GetFrameLocation) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jmethodID* method_ptr,
- jlocation* location_ptr);
-
- /* 20 : Notify Frame Pop */
- jvmtiError (JNICALL *NotifyFramePop) (jvmtiEnv* env,
- jthread thread,
- jint depth);
-
- /* 21 : Get Local Variable - Object */
- jvmtiError (JNICALL *GetLocalObject) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jobject* value_ptr);
-
- /* 22 : Get Local Variable - Int */
- jvmtiError (JNICALL *GetLocalInt) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jint* value_ptr);
-
- /* 23 : Get Local Variable - Long */
- jvmtiError (JNICALL *GetLocalLong) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jlong* value_ptr);
-
- /* 24 : Get Local Variable - Float */
- jvmtiError (JNICALL *GetLocalFloat) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jfloat* value_ptr);
-
- /* 25 : Get Local Variable - Double */
- jvmtiError (JNICALL *GetLocalDouble) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jdouble* value_ptr);
-
- /* 26 : Set Local Variable - Object */
- jvmtiError (JNICALL *SetLocalObject) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jobject value);
-
- /* 27 : Set Local Variable - Int */
- jvmtiError (JNICALL *SetLocalInt) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jint value);
-
- /* 28 : Set Local Variable - Long */
- jvmtiError (JNICALL *SetLocalLong) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jlong value);
-
- /* 29 : Set Local Variable - Float */
- jvmtiError (JNICALL *SetLocalFloat) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jfloat value);
-
- /* 30 : Set Local Variable - Double */
- jvmtiError (JNICALL *SetLocalDouble) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jint slot,
- jdouble value);
-
- /* 31 : Create Raw Monitor */
- jvmtiError (JNICALL *CreateRawMonitor) (jvmtiEnv* env,
- const char* name,
- jrawMonitorID* monitor_ptr);
-
- /* 32 : Destroy Raw Monitor */
- jvmtiError (JNICALL *DestroyRawMonitor) (jvmtiEnv* env,
- jrawMonitorID monitor);
-
- /* 33 : Raw Monitor Enter */
- jvmtiError (JNICALL *RawMonitorEnter) (jvmtiEnv* env,
- jrawMonitorID monitor);
-
- /* 34 : Raw Monitor Exit */
- jvmtiError (JNICALL *RawMonitorExit) (jvmtiEnv* env,
- jrawMonitorID monitor);
-
- /* 35 : Raw Monitor Wait */
- jvmtiError (JNICALL *RawMonitorWait) (jvmtiEnv* env,
- jrawMonitorID monitor,
- jlong millis);
-
- /* 36 : Raw Monitor Notify */
- jvmtiError (JNICALL *RawMonitorNotify) (jvmtiEnv* env,
- jrawMonitorID monitor);
-
- /* 37 : Raw Monitor Notify All */
- jvmtiError (JNICALL *RawMonitorNotifyAll) (jvmtiEnv* env,
- jrawMonitorID monitor);
-
- /* 38 : Set Breakpoint */
- jvmtiError (JNICALL *SetBreakpoint) (jvmtiEnv* env,
- jmethodID method,
- jlocation location);
-
- /* 39 : Clear Breakpoint */
- jvmtiError (JNICALL *ClearBreakpoint) (jvmtiEnv* env,
- jmethodID method,
- jlocation location);
-
- /* 40 : Get Named Module */
- jvmtiError (JNICALL *GetNamedModule) (jvmtiEnv* env,
- jobject class_loader,
- const char* package_name,
- jobject* module_ptr);
-
- /* 41 : Set Field Access Watch */
- jvmtiError (JNICALL *SetFieldAccessWatch) (jvmtiEnv* env,
- jclass klass,
- jfieldID field);
-
- /* 42 : Clear Field Access Watch */
- jvmtiError (JNICALL *ClearFieldAccessWatch) (jvmtiEnv* env,
- jclass klass,
- jfieldID field);
-
- /* 43 : Set Field Modification Watch */
- jvmtiError (JNICALL *SetFieldModificationWatch) (jvmtiEnv* env,
- jclass klass,
- jfieldID field);
-
- /* 44 : Clear Field Modification Watch */
- jvmtiError (JNICALL *ClearFieldModificationWatch) (jvmtiEnv* env,
- jclass klass,
- jfieldID field);
-
- /* 45 : Is Modifiable Class */
- jvmtiError (JNICALL *IsModifiableClass) (jvmtiEnv* env,
- jclass klass,
- jboolean* is_modifiable_class_ptr);
-
- /* 46 : Allocate */
- jvmtiError (JNICALL *Allocate) (jvmtiEnv* env,
- jlong size,
- unsigned char** mem_ptr);
-
- /* 47 : Deallocate */
- jvmtiError (JNICALL *Deallocate) (jvmtiEnv* env,
- unsigned char* mem);
-
- /* 48 : Get Class Signature */
- jvmtiError (JNICALL *GetClassSignature) (jvmtiEnv* env,
- jclass klass,
- char** signature_ptr,
- char** generic_ptr);
-
- /* 49 : Get Class Status */
- jvmtiError (JNICALL *GetClassStatus) (jvmtiEnv* env,
- jclass klass,
- jint* status_ptr);
-
- /* 50 : Get Source File Name */
- jvmtiError (JNICALL *GetSourceFileName) (jvmtiEnv* env,
- jclass klass,
- char** source_name_ptr);
-
- /* 51 : Get Class Modifiers */
- jvmtiError (JNICALL *GetClassModifiers) (jvmtiEnv* env,
- jclass klass,
- jint* modifiers_ptr);
-
- /* 52 : Get Class Methods */
- jvmtiError (JNICALL *GetClassMethods) (jvmtiEnv* env,
- jclass klass,
- jint* method_count_ptr,
- jmethodID** methods_ptr);
-
- /* 53 : Get Class Fields */
- jvmtiError (JNICALL *GetClassFields) (jvmtiEnv* env,
- jclass klass,
- jint* field_count_ptr,
- jfieldID** fields_ptr);
-
- /* 54 : Get Implemented Interfaces */
- jvmtiError (JNICALL *GetImplementedInterfaces) (jvmtiEnv* env,
- jclass klass,
- jint* interface_count_ptr,
- jclass** interfaces_ptr);
-
- /* 55 : Is Interface */
- jvmtiError (JNICALL *IsInterface) (jvmtiEnv* env,
- jclass klass,
- jboolean* is_interface_ptr);
-
- /* 56 : Is Array Class */
- jvmtiError (JNICALL *IsArrayClass) (jvmtiEnv* env,
- jclass klass,
- jboolean* is_array_class_ptr);
-
- /* 57 : Get Class Loader */
- jvmtiError (JNICALL *GetClassLoader) (jvmtiEnv* env,
- jclass klass,
- jobject* classloader_ptr);
-
- /* 58 : Get Object Hash Code */
- jvmtiError (JNICALL *GetObjectHashCode) (jvmtiEnv* env,
- jobject object,
- jint* hash_code_ptr);
-
- /* 59 : Get Object Monitor Usage */
- jvmtiError (JNICALL *GetObjectMonitorUsage) (jvmtiEnv* env,
- jobject object,
- jvmtiMonitorUsage* info_ptr);
-
- /* 60 : Get Field Name (and Signature) */
- jvmtiError (JNICALL *GetFieldName) (jvmtiEnv* env,
- jclass klass,
- jfieldID field,
- char** name_ptr,
- char** signature_ptr,
- char** generic_ptr);
-
- /* 61 : Get Field Declaring Class */
- jvmtiError (JNICALL *GetFieldDeclaringClass) (jvmtiEnv* env,
- jclass klass,
- jfieldID field,
- jclass* declaring_class_ptr);
-
- /* 62 : Get Field Modifiers */
- jvmtiError (JNICALL *GetFieldModifiers) (jvmtiEnv* env,
- jclass klass,
- jfieldID field,
- jint* modifiers_ptr);
-
- /* 63 : Is Field Synthetic */
- jvmtiError (JNICALL *IsFieldSynthetic) (jvmtiEnv* env,
- jclass klass,
- jfieldID field,
- jboolean* is_synthetic_ptr);
-
- /* 64 : Get Method Name (and Signature) */
- jvmtiError (JNICALL *GetMethodName) (jvmtiEnv* env,
- jmethodID method,
- char** name_ptr,
- char** signature_ptr,
- char** generic_ptr);
-
- /* 65 : Get Method Declaring Class */
- jvmtiError (JNICALL *GetMethodDeclaringClass) (jvmtiEnv* env,
- jmethodID method,
- jclass* declaring_class_ptr);
-
- /* 66 : Get Method Modifiers */
- jvmtiError (JNICALL *GetMethodModifiers) (jvmtiEnv* env,
- jmethodID method,
- jint* modifiers_ptr);
-
- /* 67 : RESERVED */
- void *reserved67;
-
- /* 68 : Get Max Locals */
- jvmtiError (JNICALL *GetMaxLocals) (jvmtiEnv* env,
- jmethodID method,
- jint* max_ptr);
-
- /* 69 : Get Arguments Size */
- jvmtiError (JNICALL *GetArgumentsSize) (jvmtiEnv* env,
- jmethodID method,
- jint* size_ptr);
-
- /* 70 : Get Line Number Table */
- jvmtiError (JNICALL *GetLineNumberTable) (jvmtiEnv* env,
- jmethodID method,
- jint* entry_count_ptr,
- jvmtiLineNumberEntry** table_ptr);
-
- /* 71 : Get Method Location */
- jvmtiError (JNICALL *GetMethodLocation) (jvmtiEnv* env,
- jmethodID method,
- jlocation* start_location_ptr,
- jlocation* end_location_ptr);
-
- /* 72 : Get Local Variable Table */
- jvmtiError (JNICALL *GetLocalVariableTable) (jvmtiEnv* env,
- jmethodID method,
- jint* entry_count_ptr,
- jvmtiLocalVariableEntry** table_ptr);
-
- /* 73 : Set Native Method Prefix */
- jvmtiError (JNICALL *SetNativeMethodPrefix) (jvmtiEnv* env,
- const char* prefix);
-
- /* 74 : Set Native Method Prefixes */
- jvmtiError (JNICALL *SetNativeMethodPrefixes) (jvmtiEnv* env,
- jint prefix_count,
- char** prefixes);
-
- /* 75 : Get Bytecodes */
- jvmtiError (JNICALL *GetBytecodes) (jvmtiEnv* env,
- jmethodID method,
- jint* bytecode_count_ptr,
- unsigned char** bytecodes_ptr);
-
- /* 76 : Is Method Native */
- jvmtiError (JNICALL *IsMethodNative) (jvmtiEnv* env,
- jmethodID method,
- jboolean* is_native_ptr);
-
- /* 77 : Is Method Synthetic */
- jvmtiError (JNICALL *IsMethodSynthetic) (jvmtiEnv* env,
- jmethodID method,
- jboolean* is_synthetic_ptr);
-
- /* 78 : Get Loaded Classes */
- jvmtiError (JNICALL *GetLoadedClasses) (jvmtiEnv* env,
- jint* class_count_ptr,
- jclass** classes_ptr);
-
- /* 79 : Get Classloader Classes */
- jvmtiError (JNICALL *GetClassLoaderClasses) (jvmtiEnv* env,
- jobject initiating_loader,
- jint* class_count_ptr,
- jclass** classes_ptr);
-
- /* 80 : Pop Frame */
- jvmtiError (JNICALL *PopFrame) (jvmtiEnv* env,
- jthread thread);
-
- /* 81 : Force Early Return - Object */
- jvmtiError (JNICALL *ForceEarlyReturnObject) (jvmtiEnv* env,
- jthread thread,
- jobject value);
-
- /* 82 : Force Early Return - Int */
- jvmtiError (JNICALL *ForceEarlyReturnInt) (jvmtiEnv* env,
- jthread thread,
- jint value);
-
- /* 83 : Force Early Return - Long */
- jvmtiError (JNICALL *ForceEarlyReturnLong) (jvmtiEnv* env,
- jthread thread,
- jlong value);
-
- /* 84 : Force Early Return - Float */
- jvmtiError (JNICALL *ForceEarlyReturnFloat) (jvmtiEnv* env,
- jthread thread,
- jfloat value);
-
- /* 85 : Force Early Return - Double */
- jvmtiError (JNICALL *ForceEarlyReturnDouble) (jvmtiEnv* env,
- jthread thread,
- jdouble value);
-
- /* 86 : Force Early Return - Void */
- jvmtiError (JNICALL *ForceEarlyReturnVoid) (jvmtiEnv* env,
- jthread thread);
-
- /* 87 : Redefine Classes */
- jvmtiError (JNICALL *RedefineClasses) (jvmtiEnv* env,
- jint class_count,
- const jvmtiClassDefinition* class_definitions);
-
- /* 88 : Get Version Number */
- jvmtiError (JNICALL *GetVersionNumber) (jvmtiEnv* env,
- jint* version_ptr);
-
- /* 89 : Get Capabilities */
- jvmtiError (JNICALL *GetCapabilities) (jvmtiEnv* env,
- jvmtiCapabilities* capabilities_ptr);
-
- /* 90 : Get Source Debug Extension */
- jvmtiError (JNICALL *GetSourceDebugExtension) (jvmtiEnv* env,
- jclass klass,
- char** source_debug_extension_ptr);
-
- /* 91 : Is Method Obsolete */
- jvmtiError (JNICALL *IsMethodObsolete) (jvmtiEnv* env,
- jmethodID method,
- jboolean* is_obsolete_ptr);
-
- /* 92 : Suspend Thread List */
- jvmtiError (JNICALL *SuspendThreadList) (jvmtiEnv* env,
- jint request_count,
- const jthread* request_list,
- jvmtiError* results);
-
- /* 93 : Resume Thread List */
- jvmtiError (JNICALL *ResumeThreadList) (jvmtiEnv* env,
- jint request_count,
- const jthread* request_list,
- jvmtiError* results);
-
- /* 94 : RESERVED */
- void *reserved94;
-
- /* 95 : RESERVED */
- void *reserved95;
-
- /* 96 : RESERVED */
- void *reserved96;
-
- /* 97 : RESERVED */
- void *reserved97;
-
- /* 98 : RESERVED */
- void *reserved98;
-
- /* 99 : RESERVED */
- void *reserved99;
-
- /* 100 : Get All Stack Traces */
- jvmtiError (JNICALL *GetAllStackTraces) (jvmtiEnv* env,
- jint max_frame_count,
- jvmtiStackInfo** stack_info_ptr,
- jint* thread_count_ptr);
-
- /* 101 : Get Thread List Stack Traces */
- jvmtiError (JNICALL *GetThreadListStackTraces) (jvmtiEnv* env,
- jint thread_count,
- const jthread* thread_list,
- jint max_frame_count,
- jvmtiStackInfo** stack_info_ptr);
-
- /* 102 : Get Thread Local Storage */
- jvmtiError (JNICALL *GetThreadLocalStorage) (jvmtiEnv* env,
- jthread thread,
- void** data_ptr);
-
- /* 103 : Set Thread Local Storage */
- jvmtiError (JNICALL *SetThreadLocalStorage) (jvmtiEnv* env,
- jthread thread,
- const void* data);
-
- /* 104 : Get Stack Trace */
- jvmtiError (JNICALL *GetStackTrace) (jvmtiEnv* env,
- jthread thread,
- jint start_depth,
- jint max_frame_count,
- jvmtiFrameInfo* frame_buffer,
- jint* count_ptr);
-
- /* 105 : RESERVED */
- void *reserved105;
-
- /* 106 : Get Tag */
- jvmtiError (JNICALL *GetTag) (jvmtiEnv* env,
- jobject object,
- jlong* tag_ptr);
-
- /* 107 : Set Tag */
- jvmtiError (JNICALL *SetTag) (jvmtiEnv* env,
- jobject object,
- jlong tag);
-
- /* 108 : Force Garbage Collection */
- jvmtiError (JNICALL *ForceGarbageCollection) (jvmtiEnv* env);
-
- /* 109 : Iterate Over Objects Reachable From Object */
- jvmtiError (JNICALL *IterateOverObjectsReachableFromObject) (jvmtiEnv* env,
- jobject object,
- jvmtiObjectReferenceCallback object_reference_callback,
- const void* user_data);
-
- /* 110 : Iterate Over Reachable Objects */
- jvmtiError (JNICALL *IterateOverReachableObjects) (jvmtiEnv* env,
- jvmtiHeapRootCallback heap_root_callback,
- jvmtiStackReferenceCallback stack_ref_callback,
- jvmtiObjectReferenceCallback object_ref_callback,
- const void* user_data);
-
- /* 111 : Iterate Over Heap */
- jvmtiError (JNICALL *IterateOverHeap) (jvmtiEnv* env,
- jvmtiHeapObjectFilter object_filter,
- jvmtiHeapObjectCallback heap_object_callback,
- const void* user_data);
-
- /* 112 : Iterate Over Instances Of Class */
- jvmtiError (JNICALL *IterateOverInstancesOfClass) (jvmtiEnv* env,
- jclass klass,
- jvmtiHeapObjectFilter object_filter,
- jvmtiHeapObjectCallback heap_object_callback,
- const void* user_data);
-
- /* 113 : RESERVED */
- void *reserved113;
-
- /* 114 : Get Objects With Tags */
- jvmtiError (JNICALL *GetObjectsWithTags) (jvmtiEnv* env,
- jint tag_count,
- const jlong* tags,
- jint* count_ptr,
- jobject** object_result_ptr,
- jlong** tag_result_ptr);
-
- /* 115 : Follow References */
- jvmtiError (JNICALL *FollowReferences) (jvmtiEnv* env,
- jint heap_filter,
- jclass klass,
- jobject initial_object,
- const jvmtiHeapCallbacks* callbacks,
- const void* user_data);
-
- /* 116 : Iterate Through Heap */
- jvmtiError (JNICALL *IterateThroughHeap) (jvmtiEnv* env,
- jint heap_filter,
- jclass klass,
- const jvmtiHeapCallbacks* callbacks,
- const void* user_data);
-
- /* 117 : RESERVED */
- void *reserved117;
-
- /* 118 : RESERVED */
- void *reserved118;
-
- /* 119 : RESERVED */
- void *reserved119;
-
- /* 120 : Set JNI Function Table */
- jvmtiError (JNICALL *SetJNIFunctionTable) (jvmtiEnv* env,
- const jniNativeInterface* function_table);
-
- /* 121 : Get JNI Function Table */
- jvmtiError (JNICALL *GetJNIFunctionTable) (jvmtiEnv* env,
- jniNativeInterface** function_table);
-
- /* 122 : Set Event Callbacks */
- jvmtiError (JNICALL *SetEventCallbacks) (jvmtiEnv* env,
- const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks);
-
- /* 123 : Generate Events */
- jvmtiError (JNICALL *GenerateEvents) (jvmtiEnv* env,
- jvmtiEvent event_type);
-
- /* 124 : Get Extension Functions */
- jvmtiError (JNICALL *GetExtensionFunctions) (jvmtiEnv* env,
- jint* extension_count_ptr,
- jvmtiExtensionFunctionInfo** extensions);
-
- /* 125 : Get Extension Events */
- jvmtiError (JNICALL *GetExtensionEvents) (jvmtiEnv* env,
- jint* extension_count_ptr,
- jvmtiExtensionEventInfo** extensions);
-
- /* 126 : Set Extension Event Callback */
- jvmtiError (JNICALL *SetExtensionEventCallback) (jvmtiEnv* env,
- jint extension_event_index,
- jvmtiExtensionEvent callback);
-
- /* 127 : Dispose Environment */
- jvmtiError (JNICALL *DisposeEnvironment) (jvmtiEnv* env);
-
- /* 128 : Get Error Name */
- jvmtiError (JNICALL *GetErrorName) (jvmtiEnv* env,
- jvmtiError error,
- char** name_ptr);
-
- /* 129 : Get JLocation Format */
- jvmtiError (JNICALL *GetJLocationFormat) (jvmtiEnv* env,
- jvmtiJlocationFormat* format_ptr);
-
- /* 130 : Get System Properties */
- jvmtiError (JNICALL *GetSystemProperties) (jvmtiEnv* env,
- jint* count_ptr,
- char*** property_ptr);
-
- /* 131 : Get System Property */
- jvmtiError (JNICALL *GetSystemProperty) (jvmtiEnv* env,
- const char* property,
- char** value_ptr);
-
- /* 132 : Set System Property */
- jvmtiError (JNICALL *SetSystemProperty) (jvmtiEnv* env,
- const char* property,
- const char* value_ptr);
-
- /* 133 : Get Phase */
- jvmtiError (JNICALL *GetPhase) (jvmtiEnv* env,
- jvmtiPhase* phase_ptr);
-
- /* 134 : Get Current Thread CPU Timer Information */
- jvmtiError (JNICALL *GetCurrentThreadCpuTimerInfo) (jvmtiEnv* env,
- jvmtiTimerInfo* info_ptr);
-
- /* 135 : Get Current Thread CPU Time */
- jvmtiError (JNICALL *GetCurrentThreadCpuTime) (jvmtiEnv* env,
- jlong* nanos_ptr);
-
- /* 136 : Get Thread CPU Timer Information */
- jvmtiError (JNICALL *GetThreadCpuTimerInfo) (jvmtiEnv* env,
- jvmtiTimerInfo* info_ptr);
-
- /* 137 : Get Thread CPU Time */
- jvmtiError (JNICALL *GetThreadCpuTime) (jvmtiEnv* env,
- jthread thread,
- jlong* nanos_ptr);
-
- /* 138 : Get Timer Information */
- jvmtiError (JNICALL *GetTimerInfo) (jvmtiEnv* env,
- jvmtiTimerInfo* info_ptr);
-
- /* 139 : Get Time */
- jvmtiError (JNICALL *GetTime) (jvmtiEnv* env,
- jlong* nanos_ptr);
-
- /* 140 : Get Potential Capabilities */
- jvmtiError (JNICALL *GetPotentialCapabilities) (jvmtiEnv* env,
- jvmtiCapabilities* capabilities_ptr);
-
- /* 141 : RESERVED */
- void *reserved141;
-
- /* 142 : Add Capabilities */
- jvmtiError (JNICALL *AddCapabilities) (jvmtiEnv* env,
- const jvmtiCapabilities* capabilities_ptr);
-
- /* 143 : Relinquish Capabilities */
- jvmtiError (JNICALL *RelinquishCapabilities) (jvmtiEnv* env,
- const jvmtiCapabilities* capabilities_ptr);
-
- /* 144 : Get Available Processors */
- jvmtiError (JNICALL *GetAvailableProcessors) (jvmtiEnv* env,
- jint* processor_count_ptr);
-
- /* 145 : Get Class Version Numbers */
- jvmtiError (JNICALL *GetClassVersionNumbers) (jvmtiEnv* env,
- jclass klass,
- jint* minor_version_ptr,
- jint* major_version_ptr);
-
- /* 146 : Get Constant Pool */
- jvmtiError (JNICALL *GetConstantPool) (jvmtiEnv* env,
- jclass klass,
- jint* constant_pool_count_ptr,
- jint* constant_pool_byte_count_ptr,
- unsigned char** constant_pool_bytes_ptr);
-
- /* 147 : Get Environment Local Storage */
- jvmtiError (JNICALL *GetEnvironmentLocalStorage) (jvmtiEnv* env,
- void** data_ptr);
-
- /* 148 : Set Environment Local Storage */
- jvmtiError (JNICALL *SetEnvironmentLocalStorage) (jvmtiEnv* env,
- const void* data);
-
- /* 149 : Add To Bootstrap Class Loader Search */
- jvmtiError (JNICALL *AddToBootstrapClassLoaderSearch) (jvmtiEnv* env,
- const char* segment);
-
- /* 150 : Set Verbose Flag */
- jvmtiError (JNICALL *SetVerboseFlag) (jvmtiEnv* env,
- jvmtiVerboseFlag flag,
- jboolean value);
-
- /* 151 : Add To System Class Loader Search */
- jvmtiError (JNICALL *AddToSystemClassLoaderSearch) (jvmtiEnv* env,
- const char* segment);
-
- /* 152 : Retransform Classes */
- jvmtiError (JNICALL *RetransformClasses) (jvmtiEnv* env,
- jint class_count,
- const jclass* classes);
-
- /* 153 : Get Owned Monitor Stack Depth Info */
- jvmtiError (JNICALL *GetOwnedMonitorStackDepthInfo) (jvmtiEnv* env,
- jthread thread,
- jint* monitor_info_count_ptr,
- jvmtiMonitorStackDepthInfo** monitor_info_ptr);
-
- /* 154 : Get Object Size */
- jvmtiError (JNICALL *GetObjectSize) (jvmtiEnv* env,
- jobject object,
- jlong* size_ptr);
-
- /* 155 : Get Local Instance */
- jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env,
- jthread thread,
- jint depth,
- jobject* value_ptr);
-
-} jvmtiInterface_1;
-
-struct _jvmtiEnv {
- const struct jvmtiInterface_1_ *functions;
-#ifdef __cplusplus
-
-
- jvmtiError Allocate(jlong size,
- unsigned char** mem_ptr) {
- return functions->Allocate(this, size, mem_ptr);
- }
-
- jvmtiError Deallocate(unsigned char* mem) {
- return functions->Deallocate(this, mem);
- }
-
- jvmtiError GetThreadState(jthread thread,
- jint* thread_state_ptr) {
- return functions->GetThreadState(this, thread, thread_state_ptr);
- }
-
- jvmtiError GetCurrentThread(jthread* thread_ptr) {
- return functions->GetCurrentThread(this, thread_ptr);
- }
-
- jvmtiError GetAllThreads(jint* threads_count_ptr,
- jthread** threads_ptr) {
- return functions->GetAllThreads(this, threads_count_ptr, threads_ptr);
- }
-
- jvmtiError SuspendThread(jthread thread) {
- return functions->SuspendThread(this, thread);
- }
-
- jvmtiError SuspendThreadList(jint request_count,
- const jthread* request_list,
- jvmtiError* results) {
- return functions->SuspendThreadList(this, request_count, request_list, results);
- }
-
- jvmtiError ResumeThread(jthread thread) {
- return functions->ResumeThread(this, thread);
- }
-
- jvmtiError ResumeThreadList(jint request_count,
- const jthread* request_list,
- jvmtiError* results) {
- return functions->ResumeThreadList(this, request_count, request_list, results);
- }
-
- jvmtiError StopThread(jthread thread,
- jobject exception) {
- return functions->StopThread(this, thread, exception);
- }
-
- jvmtiError InterruptThread(jthread thread) {
- return functions->InterruptThread(this, thread);
- }
-
- jvmtiError GetThreadInfo(jthread thread,
- jvmtiThreadInfo* info_ptr) {
- return functions->GetThreadInfo(this, thread, info_ptr);
- }
-
- jvmtiError GetOwnedMonitorInfo(jthread thread,
- jint* owned_monitor_count_ptr,
- jobject** owned_monitors_ptr) {
- return functions->GetOwnedMonitorInfo(this, thread, owned_monitor_count_ptr, owned_monitors_ptr);
- }
-
- jvmtiError GetOwnedMonitorStackDepthInfo(jthread thread,
- jint* monitor_info_count_ptr,
- jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
- return functions->GetOwnedMonitorStackDepthInfo(this, thread, monitor_info_count_ptr, monitor_info_ptr);
- }
-
- jvmtiError GetCurrentContendedMonitor(jthread thread,
- jobject* monitor_ptr) {
- return functions->GetCurrentContendedMonitor(this, thread, monitor_ptr);
- }
-
- jvmtiError RunAgentThread(jthread thread,
- jvmtiStartFunction proc,
- const void* arg,
- jint priority) {
- return functions->RunAgentThread(this, thread, proc, arg, priority);
- }
-
- jvmtiError SetThreadLocalStorage(jthread thread,
- const void* data) {
- return functions->SetThreadLocalStorage(this, thread, data);
- }
-
- jvmtiError GetThreadLocalStorage(jthread thread,
- void** data_ptr) {
- return functions->GetThreadLocalStorage(this, thread, data_ptr);
- }
-
- jvmtiError GetTopThreadGroups(jint* group_count_ptr,
- jthreadGroup** groups_ptr) {
- return functions->GetTopThreadGroups(this, group_count_ptr, groups_ptr);
- }
-
- jvmtiError GetThreadGroupInfo(jthreadGroup group,
- jvmtiThreadGroupInfo* info_ptr) {
- return functions->GetThreadGroupInfo(this, group, info_ptr);
- }
-
- jvmtiError GetThreadGroupChildren(jthreadGroup group,
- jint* thread_count_ptr,
- jthread** threads_ptr,
- jint* group_count_ptr,
- jthreadGroup** groups_ptr) {
- return functions->GetThreadGroupChildren(this, group, thread_count_ptr, threads_ptr, group_count_ptr, groups_ptr);
- }
-
- jvmtiError GetStackTrace(jthread thread,
- jint start_depth,
- jint max_frame_count,
- jvmtiFrameInfo* frame_buffer,
- jint* count_ptr) {
- return functions->GetStackTrace(this, thread, start_depth, max_frame_count, frame_buffer, count_ptr);
- }
-
- jvmtiError GetAllStackTraces(jint max_frame_count,
- jvmtiStackInfo** stack_info_ptr,
- jint* thread_count_ptr) {
- return functions->GetAllStackTraces(this, max_frame_count, stack_info_ptr, thread_count_ptr);
- }
-
- jvmtiError GetThreadListStackTraces(jint thread_count,
- const jthread* thread_list,
- jint max_frame_count,
- jvmtiStackInfo** stack_info_ptr) {
- return functions->GetThreadListStackTraces(this, thread_count, thread_list, max_frame_count, stack_info_ptr);
- }
-
- jvmtiError GetFrameCount(jthread thread,
- jint* count_ptr) {
- return functions->GetFrameCount(this, thread, count_ptr);
- }
-
- jvmtiError PopFrame(jthread thread) {
- return functions->PopFrame(this, thread);
- }
-
- jvmtiError GetFrameLocation(jthread thread,
- jint depth,
- jmethodID* method_ptr,
- jlocation* location_ptr) {
- return functions->GetFrameLocation(this, thread, depth, method_ptr, location_ptr);
- }
-
- jvmtiError NotifyFramePop(jthread thread,
- jint depth) {
- return functions->NotifyFramePop(this, thread, depth);
- }
-
- jvmtiError ForceEarlyReturnObject(jthread thread,
- jobject value) {
- return functions->ForceEarlyReturnObject(this, thread, value);
- }
-
- jvmtiError ForceEarlyReturnInt(jthread thread,
- jint value) {
- return functions->ForceEarlyReturnInt(this, thread, value);
- }
-
- jvmtiError ForceEarlyReturnLong(jthread thread,
- jlong value) {
- return functions->ForceEarlyReturnLong(this, thread, value);
- }
-
- jvmtiError ForceEarlyReturnFloat(jthread thread,
- jfloat value) {
- return functions->ForceEarlyReturnFloat(this, thread, value);
- }
-
- jvmtiError ForceEarlyReturnDouble(jthread thread,
- jdouble value) {
- return functions->ForceEarlyReturnDouble(this, thread, value);
- }
-
- jvmtiError ForceEarlyReturnVoid(jthread thread) {
- return functions->ForceEarlyReturnVoid(this, thread);
- }
-
- jvmtiError FollowReferences(jint heap_filter,
- jclass klass,
- jobject initial_object,
- const jvmtiHeapCallbacks* callbacks,
- const void* user_data) {
- return functions->FollowReferences(this, heap_filter, klass, initial_object, callbacks, user_data);
- }
-
- jvmtiError IterateThroughHeap(jint heap_filter,
- jclass klass,
- const jvmtiHeapCallbacks* callbacks,
- const void* user_data) {
- return functions->IterateThroughHeap(this, heap_filter, klass, callbacks, user_data);
- }
-
- jvmtiError GetTag(jobject object,
- jlong* tag_ptr) {
- return functions->GetTag(this, object, tag_ptr);
- }
-
- jvmtiError SetTag(jobject object,
- jlong tag) {
- return functions->SetTag(this, object, tag);
- }
-
- jvmtiError GetObjectsWithTags(jint tag_count,
- const jlong* tags,
- jint* count_ptr,
- jobject** object_result_ptr,
- jlong** tag_result_ptr) {
- return functions->GetObjectsWithTags(this, tag_count, tags, count_ptr, object_result_ptr, tag_result_ptr);
- }
-
- jvmtiError ForceGarbageCollection() {
- return functions->ForceGarbageCollection(this);
- }
-
- jvmtiError IterateOverObjectsReachableFromObject(jobject object,
- jvmtiObjectReferenceCallback object_reference_callback,
- const void* user_data) {
- return functions->IterateOverObjectsReachableFromObject(this, object, object_reference_callback, user_data);
- }
-
- jvmtiError IterateOverReachableObjects(jvmtiHeapRootCallback heap_root_callback,
- jvmtiStackReferenceCallback stack_ref_callback,
- jvmtiObjectReferenceCallback object_ref_callback,
- const void* user_data) {
- return functions->IterateOverReachableObjects(this, heap_root_callback, stack_ref_callback, object_ref_callback, user_data);
- }
-
- jvmtiError IterateOverHeap(jvmtiHeapObjectFilter object_filter,
- jvmtiHeapObjectCallback heap_object_callback,
- const void* user_data) {
- return functions->IterateOverHeap(this, object_filter, heap_object_callback, user_data);
- }
-
- jvmtiError IterateOverInstancesOfClass(jclass klass,
- jvmtiHeapObjectFilter object_filter,
- jvmtiHeapObjectCallback heap_object_callback,
- const void* user_data) {
- return functions->IterateOverInstancesOfClass(this, klass, object_filter, heap_object_callback, user_data);
- }
-
- jvmtiError GetLocalObject(jthread thread,
- jint depth,
- jint slot,
- jobject* value_ptr) {
- return functions->GetLocalObject(this, thread, depth, slot, value_ptr);
- }
-
- jvmtiError GetLocalInstance(jthread thread,
- jint depth,
- jobject* value_ptr) {
- return functions->GetLocalInstance(this, thread, depth, value_ptr);
- }
-
- jvmtiError GetLocalInt(jthread thread,
- jint depth,
- jint slot,
- jint* value_ptr) {
- return functions->GetLocalInt(this, thread, depth, slot, value_ptr);
- }
-
- jvmtiError GetLocalLong(jthread thread,
- jint depth,
- jint slot,
- jlong* value_ptr) {
- return functions->GetLocalLong(this, thread, depth, slot, value_ptr);
- }
-
- jvmtiError GetLocalFloat(jthread thread,
- jint depth,
- jint slot,
- jfloat* value_ptr) {
- return functions->GetLocalFloat(this, thread, depth, slot, value_ptr);
- }
-
- jvmtiError GetLocalDouble(jthread thread,
- jint depth,
- jint slot,
- jdouble* value_ptr) {
- return functions->GetLocalDouble(this, thread, depth, slot, value_ptr);
- }
-
- jvmtiError SetLocalObject(jthread thread,
- jint depth,
- jint slot,
- jobject value) {
- return functions->SetLocalObject(this, thread, depth, slot, value);
- }
-
- jvmtiError SetLocalInt(jthread thread,
- jint depth,
- jint slot,
- jint value) {
- return functions->SetLocalInt(this, thread, depth, slot, value);
- }
-
- jvmtiError SetLocalLong(jthread thread,
- jint depth,
- jint slot,
- jlong value) {
- return functions->SetLocalLong(this, thread, depth, slot, value);
- }
-
- jvmtiError SetLocalFloat(jthread thread,
- jint depth,
- jint slot,
- jfloat value) {
- return functions->SetLocalFloat(this, thread, depth, slot, value);
- }
-
- jvmtiError SetLocalDouble(jthread thread,
- jint depth,
- jint slot,
- jdouble value) {
- return functions->SetLocalDouble(this, thread, depth, slot, value);
- }
-
- jvmtiError SetBreakpoint(jmethodID method,
- jlocation location) {
- return functions->SetBreakpoint(this, method, location);
- }
-
- jvmtiError ClearBreakpoint(jmethodID method,
- jlocation location) {
- return functions->ClearBreakpoint(this, method, location);
- }
-
- jvmtiError SetFieldAccessWatch(jclass klass,
- jfieldID field) {
- return functions->SetFieldAccessWatch(this, klass, field);
- }
-
- jvmtiError ClearFieldAccessWatch(jclass klass,
- jfieldID field) {
- return functions->ClearFieldAccessWatch(this, klass, field);
- }
-
- jvmtiError SetFieldModificationWatch(jclass klass,
- jfieldID field) {
- return functions->SetFieldModificationWatch(this, klass, field);
- }
-
- jvmtiError ClearFieldModificationWatch(jclass klass,
- jfieldID field) {
- return functions->ClearFieldModificationWatch(this, klass, field);
- }
-
- jvmtiError GetAllModules(jint* module_count_ptr,
- jobject** modules_ptr) {
- return functions->GetAllModules(this, module_count_ptr, modules_ptr);
- }
-
- jvmtiError GetNamedModule(jobject class_loader,
- const char* package_name,
- jobject* module_ptr) {
- return functions->GetNamedModule(this, class_loader, package_name, module_ptr);
- }
-
- jvmtiError GetLoadedClasses(jint* class_count_ptr,
- jclass** classes_ptr) {
- return functions->GetLoadedClasses(this, class_count_ptr, classes_ptr);
- }
-
- jvmtiError GetClassLoaderClasses(jobject initiating_loader,
- jint* class_count_ptr,
- jclass** classes_ptr) {
- return functions->GetClassLoaderClasses(this, initiating_loader, class_count_ptr, classes_ptr);
- }
-
- jvmtiError GetClassSignature(jclass klass,
- char** signature_ptr,
- char** generic_ptr) {
- return functions->GetClassSignature(this, klass, signature_ptr, generic_ptr);
- }
-
- jvmtiError GetClassStatus(jclass klass,
- jint* status_ptr) {
- return functions->GetClassStatus(this, klass, status_ptr);
- }
-
- jvmtiError GetSourceFileName(jclass klass,
- char** source_name_ptr) {
- return functions->GetSourceFileName(this, klass, source_name_ptr);
- }
-
- jvmtiError GetClassModifiers(jclass klass,
- jint* modifiers_ptr) {
- return functions->GetClassModifiers(this, klass, modifiers_ptr);
- }
-
- jvmtiError GetClassMethods(jclass klass,
- jint* method_count_ptr,
- jmethodID** methods_ptr) {
- return functions->GetClassMethods(this, klass, method_count_ptr, methods_ptr);
- }
-
- jvmtiError GetClassFields(jclass klass,
- jint* field_count_ptr,
- jfieldID** fields_ptr) {
- return functions->GetClassFields(this, klass, field_count_ptr, fields_ptr);
- }
-
- jvmtiError GetImplementedInterfaces(jclass klass,
- jint* interface_count_ptr,
- jclass** interfaces_ptr) {
- return functions->GetImplementedInterfaces(this, klass, interface_count_ptr, interfaces_ptr);
- }
-
- jvmtiError GetClassVersionNumbers(jclass klass,
- jint* minor_version_ptr,
- jint* major_version_ptr) {
- return functions->GetClassVersionNumbers(this, klass, minor_version_ptr, major_version_ptr);
- }
-
- jvmtiError GetConstantPool(jclass klass,
- jint* constant_pool_count_ptr,
- jint* constant_pool_byte_count_ptr,
- unsigned char** constant_pool_bytes_ptr) {
- return functions->GetConstantPool(this, klass, constant_pool_count_ptr, constant_pool_byte_count_ptr, constant_pool_bytes_ptr);
- }
-
- jvmtiError IsInterface(jclass klass,
- jboolean* is_interface_ptr) {
- return functions->IsInterface(this, klass, is_interface_ptr);
- }
-
- jvmtiError IsArrayClass(jclass klass,
- jboolean* is_array_class_ptr) {
- return functions->IsArrayClass(this, klass, is_array_class_ptr);
- }
-
- jvmtiError IsModifiableClass(jclass klass,
- jboolean* is_modifiable_class_ptr) {
- return functions->IsModifiableClass(this, klass, is_modifiable_class_ptr);
- }
-
- jvmtiError GetClassLoader(jclass klass,
- jobject* classloader_ptr) {
- return functions->GetClassLoader(this, klass, classloader_ptr);
- }
-
- jvmtiError GetSourceDebugExtension(jclass klass,
- char** source_debug_extension_ptr) {
- return functions->GetSourceDebugExtension(this, klass, source_debug_extension_ptr);
- }
-
- jvmtiError RetransformClasses(jint class_count,
- const jclass* classes) {
- return functions->RetransformClasses(this, class_count, classes);
- }
-
- jvmtiError RedefineClasses(jint class_count,
- const jvmtiClassDefinition* class_definitions) {
- return functions->RedefineClasses(this, class_count, class_definitions);
- }
-
- jvmtiError GetObjectSize(jobject object,
- jlong* size_ptr) {
- return functions->GetObjectSize(this, object, size_ptr);
- }
-
- jvmtiError GetObjectHashCode(jobject object,
- jint* hash_code_ptr) {
- return functions->GetObjectHashCode(this, object, hash_code_ptr);
- }
-
- jvmtiError GetObjectMonitorUsage(jobject object,
- jvmtiMonitorUsage* info_ptr) {
- return functions->GetObjectMonitorUsage(this, object, info_ptr);
- }
-
- jvmtiError GetFieldName(jclass klass,
- jfieldID field,
- char** name_ptr,
- char** signature_ptr,
- char** generic_ptr) {
- return functions->GetFieldName(this, klass, field, name_ptr, signature_ptr, generic_ptr);
- }
-
- jvmtiError GetFieldDeclaringClass(jclass klass,
- jfieldID field,
- jclass* declaring_class_ptr) {
- return functions->GetFieldDeclaringClass(this, klass, field, declaring_class_ptr);
- }
-
- jvmtiError GetFieldModifiers(jclass klass,
- jfieldID field,
- jint* modifiers_ptr) {
- return functions->GetFieldModifiers(this, klass, field, modifiers_ptr);
- }
-
- jvmtiError IsFieldSynthetic(jclass klass,
- jfieldID field,
- jboolean* is_synthetic_ptr) {
- return functions->IsFieldSynthetic(this, klass, field, is_synthetic_ptr);
- }
-
- jvmtiError GetMethodName(jmethodID method,
- char** name_ptr,
- char** signature_ptr,
- char** generic_ptr) {
- return functions->GetMethodName(this, method, name_ptr, signature_ptr, generic_ptr);
- }
-
- jvmtiError GetMethodDeclaringClass(jmethodID method,
- jclass* declaring_class_ptr) {
- return functions->GetMethodDeclaringClass(this, method, declaring_class_ptr);
- }
-
- jvmtiError GetMethodModifiers(jmethodID method,
- jint* modifiers_ptr) {
- return functions->GetMethodModifiers(this, method, modifiers_ptr);
- }
-
- jvmtiError GetMaxLocals(jmethodID method,
- jint* max_ptr) {
- return functions->GetMaxLocals(this, method, max_ptr);
- }
-
- jvmtiError GetArgumentsSize(jmethodID method,
- jint* size_ptr) {
- return functions->GetArgumentsSize(this, method, size_ptr);
- }
-
- jvmtiError GetLineNumberTable(jmethodID method,
- jint* entry_count_ptr,
- jvmtiLineNumberEntry** table_ptr) {
- return functions->GetLineNumberTable(this, method, entry_count_ptr, table_ptr);
- }
-
- jvmtiError GetMethodLocation(jmethodID method,
- jlocation* start_location_ptr,
- jlocation* end_location_ptr) {
- return functions->GetMethodLocation(this, method, start_location_ptr, end_location_ptr);
- }
-
- jvmtiError GetLocalVariableTable(jmethodID method,
- jint* entry_count_ptr,
- jvmtiLocalVariableEntry** table_ptr) {
- return functions->GetLocalVariableTable(this, method, entry_count_ptr, table_ptr);
- }
-
- jvmtiError GetBytecodes(jmethodID method,
- jint* bytecode_count_ptr,
- unsigned char** bytecodes_ptr) {
- return functions->GetBytecodes(this, method, bytecode_count_ptr, bytecodes_ptr);
- }
-
- jvmtiError IsMethodNative(jmethodID method,
- jboolean* is_native_ptr) {
- return functions->IsMethodNative(this, method, is_native_ptr);
- }
-
- jvmtiError IsMethodSynthetic(jmethodID method,
- jboolean* is_synthetic_ptr) {
- return functions->IsMethodSynthetic(this, method, is_synthetic_ptr);
- }
-
- jvmtiError IsMethodObsolete(jmethodID method,
- jboolean* is_obsolete_ptr) {
- return functions->IsMethodObsolete(this, method, is_obsolete_ptr);
- }
-
- jvmtiError SetNativeMethodPrefix(const char* prefix) {
- return functions->SetNativeMethodPrefix(this, prefix);
- }
-
- jvmtiError SetNativeMethodPrefixes(jint prefix_count,
- char** prefixes) {
- return functions->SetNativeMethodPrefixes(this, prefix_count, prefixes);
- }
-
- jvmtiError CreateRawMonitor(const char* name,
- jrawMonitorID* monitor_ptr) {
- return functions->CreateRawMonitor(this, name, monitor_ptr);
- }
-
- jvmtiError DestroyRawMonitor(jrawMonitorID monitor) {
- return functions->DestroyRawMonitor(this, monitor);
- }
-
- jvmtiError RawMonitorEnter(jrawMonitorID monitor) {
- return functions->RawMonitorEnter(this, monitor);
- }
-
- jvmtiError RawMonitorExit(jrawMonitorID monitor) {
- return functions->RawMonitorExit(this, monitor);
- }
-
- jvmtiError RawMonitorWait(jrawMonitorID monitor,
- jlong millis) {
- return functions->RawMonitorWait(this, monitor, millis);
- }
-
- jvmtiError RawMonitorNotify(jrawMonitorID monitor) {
- return functions->RawMonitorNotify(this, monitor);
- }
-
- jvmtiError RawMonitorNotifyAll(jrawMonitorID monitor) {
- return functions->RawMonitorNotifyAll(this, monitor);
- }
-
- jvmtiError SetJNIFunctionTable(const jniNativeInterface* function_table) {
- return functions->SetJNIFunctionTable(this, function_table);
- }
-
- jvmtiError GetJNIFunctionTable(jniNativeInterface** function_table) {
- return functions->GetJNIFunctionTable(this, function_table);
- }
-
- jvmtiError SetEventCallbacks(const jvmtiEventCallbacks* callbacks,
- jint size_of_callbacks) {
- return functions->SetEventCallbacks(this, callbacks, size_of_callbacks);
- }
-
- jvmtiError SetEventNotificationMode(jvmtiEventMode mode,
- jvmtiEvent event_type,
- jthread event_thread,
- ...) {
- return functions->SetEventNotificationMode(this, mode, event_type, event_thread);
- }
-
- jvmtiError GenerateEvents(jvmtiEvent event_type) {
- return functions->GenerateEvents(this, event_type);
- }
-
- jvmtiError GetExtensionFunctions(jint* extension_count_ptr,
- jvmtiExtensionFunctionInfo** extensions) {
- return functions->GetExtensionFunctions(this, extension_count_ptr, extensions);
- }
-
- jvmtiError GetExtensionEvents(jint* extension_count_ptr,
- jvmtiExtensionEventInfo** extensions) {
- return functions->GetExtensionEvents(this, extension_count_ptr, extensions);
- }
-
- jvmtiError SetExtensionEventCallback(jint extension_event_index,
- jvmtiExtensionEvent callback) {
- return functions->SetExtensionEventCallback(this, extension_event_index, callback);
- }
-
- jvmtiError GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) {
- return functions->GetPotentialCapabilities(this, capabilities_ptr);
- }
-
- jvmtiError AddCapabilities(const jvmtiCapabilities* capabilities_ptr) {
- return functions->AddCapabilities(this, capabilities_ptr);
- }
-
- jvmtiError RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) {
- return functions->RelinquishCapabilities(this, capabilities_ptr);
- }
-
- jvmtiError GetCapabilities(jvmtiCapabilities* capabilities_ptr) {
- return functions->GetCapabilities(this, capabilities_ptr);
- }
-
- jvmtiError GetCurrentThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
- return functions->GetCurrentThreadCpuTimerInfo(this, info_ptr);
- }
-
- jvmtiError GetCurrentThreadCpuTime(jlong* nanos_ptr) {
- return functions->GetCurrentThreadCpuTime(this, nanos_ptr);
- }
-
- jvmtiError GetThreadCpuTimerInfo(jvmtiTimerInfo* info_ptr) {
- return functions->GetThreadCpuTimerInfo(this, info_ptr);
- }
-
- jvmtiError GetThreadCpuTime(jthread thread,
- jlong* nanos_ptr) {
- return functions->GetThreadCpuTime(this, thread, nanos_ptr);
- }
-
- jvmtiError GetTimerInfo(jvmtiTimerInfo* info_ptr) {
- return functions->GetTimerInfo(this, info_ptr);
- }
-
- jvmtiError GetTime(jlong* nanos_ptr) {
- return functions->GetTime(this, nanos_ptr);
- }
-
- jvmtiError GetAvailableProcessors(jint* processor_count_ptr) {
- return functions->GetAvailableProcessors(this, processor_count_ptr);
- }
-
- jvmtiError AddToBootstrapClassLoaderSearch(const char* segment) {
- return functions->AddToBootstrapClassLoaderSearch(this, segment);
- }
-
- jvmtiError AddToSystemClassLoaderSearch(const char* segment) {
- return functions->AddToSystemClassLoaderSearch(this, segment);
- }
-
- jvmtiError GetSystemProperties(jint* count_ptr,
- char*** property_ptr) {
- return functions->GetSystemProperties(this, count_ptr, property_ptr);
- }
-
- jvmtiError GetSystemProperty(const char* property,
- char** value_ptr) {
- return functions->GetSystemProperty(this, property, value_ptr);
- }
-
- jvmtiError SetSystemProperty(const char* property,
- const char* value_ptr) {
- return functions->SetSystemProperty(this, property, value_ptr);
- }
-
- jvmtiError GetPhase(jvmtiPhase* phase_ptr) {
- return functions->GetPhase(this, phase_ptr);
- }
-
- jvmtiError DisposeEnvironment() {
- return functions->DisposeEnvironment(this);
- }
-
- jvmtiError SetEnvironmentLocalStorage(const void* data) {
- return functions->SetEnvironmentLocalStorage(this, data);
- }
-
- jvmtiError GetEnvironmentLocalStorage(void** data_ptr) {
- return functions->GetEnvironmentLocalStorage(this, data_ptr);
- }
-
- jvmtiError GetVersionNumber(jint* version_ptr) {
- return functions->GetVersionNumber(this, version_ptr);
- }
-
- jvmtiError GetErrorName(jvmtiError error,
- char** name_ptr) {
- return functions->GetErrorName(this, error, name_ptr);
- }
-
- jvmtiError SetVerboseFlag(jvmtiVerboseFlag flag,
- jboolean value) {
- return functions->SetVerboseFlag(this, flag, value);
- }
-
- jvmtiError GetJLocationFormat(jvmtiJlocationFormat* format_ptr) {
- return functions->GetJLocationFormat(this, format_ptr);
- }
-
-#endif /* __cplusplus */
-};
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif /* __cplusplus */
-
-#endif /* !_JAVA_JVMTI_H_ */
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/launcher/defines.h
--- a/jdk/src/java.base/share/native/launcher/defines.h Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/launcher/defines.h Fri Nov 11 16:44:36 2016 +0100
@@ -51,16 +51,6 @@
static char* const_progname = NULL;
#endif
static const char* const_jargs[] = JAVA_ARGS;
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-static const char* const_appclasspath[] = { NULL };
-#else
-static const char* const_appclasspath[] = APP_CLASSPATH;
-#endif /* APP_CLASSPATH */
#else /* !JAVA_ARGS */
#define HAS_JAVA_ARGS JNI_FALSE
static const char* const_progname = "java";
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/launcher/main.c
--- a/jdk/src/java.base/share/native/launcher/main.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/launcher/main.c Fri Nov 11 16:44:36 2016 +0100
@@ -83,7 +83,7 @@
int WINAPI
WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
{
- int margc, appclassc;
+ int margc;
char** margv;
const jboolean const_javaw = JNI_TRUE;
@@ -93,7 +93,7 @@
int
main(int argc, char **argv)
{
- int margc, appclassc;
+ int margc;
char** margv;
const jboolean const_javaw = JNI_FALSE;
#endif /* JAVAW */
@@ -148,14 +148,9 @@
margv = args->elements;
}
#endif /* WIN32 */
- if (const_appclasspath[0] == NULL) {
- appclassc = 0;
- } else {
- appclassc = sizeof(const_appclasspath) / sizeof(char *);
- }
return JLI_Launch(margc, margv,
sizeof(const_jargs) / sizeof(char *), const_jargs,
- appclassc, const_appclasspath,
+ 0, NULL,
VERSION_STRING,
DOT_VERSION,
(const_progname != NULL) ? const_progname : *margv,
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libjava/StackFrameInfo.c
--- a/jdk/src/java.base/share/native/libjava/StackFrameInfo.c Mon Nov 14 11:15:43 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Implementation of class StackFrameInfo
- */
-
-#include
-#include
-
-#include "jni.h"
-#include "jvm.h"
-
-#include "java_lang_StackFrameInfo.h"
-
-
-/*
- * Class: java_lang_StackFrameInfo
- * Method: toStackTraceElement0
- * Signature: (Ljava/lang/StackTraceElement;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_StackFrameInfo_toStackTraceElement0
- (JNIEnv *env, jobject stackframeinfo, jobject stacktraceinfo) {
- JVM_ToStackTraceElement(env, stackframeinfo, stacktraceinfo);
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libjava/StackTraceElement.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjava/StackTraceElement.c Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include
+#include
+
+#include "jni.h"
+#include "jvm.h"
+
+#include "java_lang_StackTraceElement.h"
+
+JNIEXPORT void JNICALL Java_java_lang_StackTraceElement_initStackTraceElement
+ (JNIEnv *env, jobject dummy, jobject element, jobject stackframeinfo) {
+ JVM_InitStackTraceElement(env, element, stackframeinfo);
+}
+
+JNIEXPORT void JNICALL Java_java_lang_StackTraceElement_initStackTraceElements
+ (JNIEnv *env, jobject dummy, jobjectArray elements, jobject throwable)
+{
+ JVM_InitStackTraceElementArray(env, elements, throwable);
+}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libjava/Throwable.c
--- a/jdk/src/java.base/share/native/libjava/Throwable.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/libjava/Throwable.c Fri Nov 11 16:44:36 2016 +0100
@@ -49,10 +49,3 @@
JVM_FillInStackTrace(env, throwable);
return throwable;
}
-
-JNIEXPORT void JNICALL
-Java_java_lang_Throwable_getStackTraceElements(JNIEnv *env,
- jobject throwable, jobjectArray elements)
-{
- JVM_GetStackTraceElements(env, throwable, elements);
-}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libjli/java.c
--- a/jdk/src/java.base/share/native/libjli/java.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/libjli/java.c Fri Nov 11 16:44:36 2016 +0100
@@ -1664,19 +1664,21 @@
AddOption(apphome, NULL);
/* How big is the application's classpath? */
- size = 40; /* 40: "-Djava.class.path=" */
- for (i = 0; i < cpathc; i++) {
- size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */
+ if (cpathc > 0) {
+ size = 40; /* 40: "-Djava.class.path=" */
+ for (i = 0; i < cpathc; i++) {
+ size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */
+ }
+ appcp = (char *)JLI_MemAlloc(size + 1);
+ JLI_StrCpy(appcp, "-Djava.class.path=");
+ for (i = 0; i < cpathc; i++) {
+ JLI_StrCat(appcp, home); /* c:\program files\myapp */
+ JLI_StrCat(appcp, cpathv[i]); /* \lib\myapp.jar */
+ JLI_StrCat(appcp, separator); /* ; */
+ }
+ appcp[JLI_StrLen(appcp)-1] = '\0'; /* remove trailing path separator */
+ AddOption(appcp, NULL);
}
- appcp = (char *)JLI_MemAlloc(size + 1);
- JLI_StrCpy(appcp, "-Djava.class.path=");
- for (i = 0; i < cpathc; i++) {
- JLI_StrCat(appcp, home); /* c:\program files\myapp */
- JLI_StrCat(appcp, cpathv[i]); /* \lib\myapp.jar */
- JLI_StrCat(appcp, separator); /* ; */
- }
- appcp[JLI_StrLen(appcp)-1] = '\0'; /* remove trailing path separator */
- AddOption(appcp, NULL);
return JNI_TRUE;
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libnet/net_util.c
--- a/jdk/src/java.base/share/native/libnet/net_util.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/libnet/net_util.c Fri Nov 11 16:44:36 2016 +0100
@@ -23,20 +23,19 @@
* questions.
*/
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
-int IPv6_supported() ;
-int reuseport_supported() ;
+#include "java_net_InetAddress.h"
+
+int IPv6_supported();
+int reuseport_supported();
static int IPv6_available;
static int REUSEPORT_available;
JNIEXPORT jint JNICALL ipv6_available()
{
- return IPv6_available ;
+ return IPv6_available;
}
JNIEXPORT jint JNICALL reuseport_available()
@@ -204,13 +203,8 @@
JNIEXPORT jobject JNICALL
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
jobject iaObj;
-#ifdef AF_INET6
if (him->sa_family == AF_INET6) {
-#ifdef WIN32
- struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
-#else
struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
-#endif
jbyte *caddr = (jbyte *)&(him6->sin6_addr);
if (NET_IsIPv4Mapped(caddr)) {
int address;
@@ -218,7 +212,7 @@
CHECK_NULL_RETURN(iaObj, NULL);
address = NET_IPv4MappedToIPv4(caddr);
setInetAddress_addr(env, iaObj, address);
- setInetAddress_family(env, iaObj, IPv4);
+ setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
} else {
jint scope;
jboolean ret;
@@ -227,21 +221,19 @@
ret = setInet6Address_ipaddress(env, iaObj, (char *)&(him6->sin6_addr));
if (ret == JNI_FALSE)
return NULL;
- setInetAddress_family(env, iaObj, IPv6);
+ setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
scope = getScopeID(him);
setInet6Address_scopeid(env, iaObj, scope);
}
*port = ntohs(him6->sin6_port);
- } else
-#endif /* AF_INET6 */
- {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
- iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
- CHECK_NULL_RETURN(iaObj, NULL);
- setInetAddress_family(env, iaObj, IPv4);
- setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
- *port = ntohs(him4->sin_port);
- }
+ } else {
+ struct sockaddr_in *him4 = (struct sockaddr_in *)him;
+ iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
+ CHECK_NULL_RETURN(iaObj, NULL);
+ setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
+ setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
+ *port = ntohs(him4->sin_port);
+ }
return iaObj;
}
@@ -250,14 +242,10 @@
{
jint family = AF_INET;
-#ifdef AF_INET6
- family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+ family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+ AF_INET : AF_INET6;
if (him->sa_family == AF_INET6) {
-#ifdef WIN32
- struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
-#else
struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
-#endif
jbyte *caddrNew = (jbyte *)&(him6->sin6_addr);
if (NET_IsIPv4Mapped(caddrNew)) {
int addrNew;
@@ -287,22 +275,20 @@
return JNI_FALSE;
}
}
- } else
-#endif /* AF_INET6 */
- {
- struct sockaddr_in *him4 = (struct sockaddr_in *)him;
- int addrNew, addrCur;
- if (family != AF_INET) {
- return JNI_FALSE;
- }
- addrNew = ntohl(him4->sin_addr.s_addr);
- addrCur = getInetAddress_addr(env, iaObj);
- if (addrNew == addrCur) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
+ } else {
+ struct sockaddr_in *him4 = (struct sockaddr_in *)him;
+ int addrNew, addrCur;
+ if (family != AF_INET) {
+ return JNI_FALSE;
}
+ addrNew = ntohl(him4->sin_addr.s_addr);
+ addrCur = getInetAddress_addr(env, iaObj);
+ if (addrNew == addrCur) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+ }
}
unsigned short
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/share/native/libnet/net_util.h
--- a/jdk/src/java.base/share/native/libnet/net_util.h Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/share/native/libnet/net_util.h Fri Nov 11 16:44:36 2016 +0100
@@ -36,12 +36,6 @@
#define MAX_PACKET_LEN 65536
-#define IPv4 1
-#define IPv6 2
-
-#define NET_ERROR(env, ex, msg) \
-{ if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg); }
-
#define NET_WAIT_READ 0x01
#define NET_WAIT_WRITE 0x02
#define NET_WAIT_CONNECT 0x04
@@ -127,45 +121,43 @@
JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls);
JNIEXPORT void JNICALL NET_ThrowNew(JNIEnv *env, int errorNum, char *msg);
+
int NET_GetError();
void NET_ThrowCurrent(JNIEnv *env, char *msg);
jfieldID NET_GetFileDescriptorID(JNIEnv *env);
-JNIEXPORT jint JNICALL ipv6_available() ;
+JNIEXPORT jint JNICALL ipv6_available();
-JNIEXPORT jint JNICALL reuseport_available() ;
+JNIEXPORT jint JNICALL reuseport_available();
JNIEXPORT int JNICALL
-NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean v4MappedAddress);
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
+ struct sockaddr *him, int *len,
+ jboolean v4MappedAddress);
JNIEXPORT jobject JNICALL
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
void platformInit();
+
void parseExclusiveBindProperty(JNIEnv *env);
-void
-NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
+void NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
-JNIEXPORT jint JNICALL
-NET_GetPortFromSockaddr(struct sockaddr *him);
+JNIEXPORT jint JNICALL NET_GetPortFromSockaddr(struct sockaddr *him);
JNIEXPORT jint JNICALL
NET_SockaddrEqualsInetAddress(JNIEnv *env,struct sockaddr *him, jobject iaObj);
-int
-NET_IsIPv4Mapped(jbyte* caddr);
+int NET_IsIPv4Mapped(jbyte* caddr);
-int
-NET_IPv4MappedToIPv4(jbyte* caddr);
+int NET_IPv4MappedToIPv4(jbyte* caddr);
-int
-NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
+int NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
-int
-NET_IsZeroAddr(jbyte* caddr);
+int NET_IsZeroAddr(jbyte* caddr);
/* Socket operations
*
@@ -191,9 +183,9 @@
JNIEXPORT jint JNICALL
NET_EnableFastTcpLoopback(int fd);
-int getScopeID (struct sockaddr *);
+int getScopeID(struct sockaddr *);
-int cmpScopeID (unsigned int, struct sockaddr *);
+int cmpScopeID(unsigned int, struct sockaddr *);
unsigned short in_cksum(unsigned short *addr, int len);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/conf/s390x/jvm.cfg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/unix/conf/s390x/jvm.cfg Fri Nov 11 16:44:36 2016 +0100
@@ -0,0 +1,34 @@
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# 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.
+#
+# List of JVMs that can be used as an option to java, javac, etc.
+# Order is important -- first in this list is the default JVM.
+# NOTE that this both this file and its format are UNSUPPORTED and
+# WILL GO AWAY in a future release.
+#
+# You may also select a JVM in an arbitrary location with the
+# "-XXaltjvm=" option, but that too is unsupported
+# and may not be available in a future release.
+#
+-server KNOWN
+-client IGNORE
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c
--- a/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,27 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
-#include
#include
-#include
+#include
#include
-#include
#include
#include
-#include
+#include
#include
-#include
-#include
+#include
-#ifdef _ALLBSD_SOURCE
-#include
-#include
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
#include "java_net_Inet4AddressImpl.h"
@@ -293,13 +283,12 @@
addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff);
memset((char *) &him4, 0, sizeof(him4));
- him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_addr.s_addr = htonl(addr);
him4.sin_family = AF_INET;
sa = (struct sockaddr *) &him4;
len = sizeof(him4);
- error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
- NI_NAMEREQD);
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
if (!error) {
ret = (*env)->NewStringUTF(env, host);
@@ -443,7 +432,7 @@
if (!skip) {
struct addrinfo *next
- = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+ = (struct addrinfo *)malloc(sizeof(struct addrinfo));
if (!next) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
ret = NULL;
@@ -528,13 +517,12 @@
addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff);
memset((void *) &him4, 0, sizeof(him4));
- him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_addr.s_addr = htonl(addr);
him4.sin_family = AF_INET;
sa = (struct sockaddr *) &him4;
len = sizeof(him4);
- error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
- NI_NAMEREQD);
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
if (!error) {
ret = (*env)->NewStringUTF(env, host);
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c
--- a/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,29 +22,21 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
+#include
+#include
#include
#include
-#include
#include
-#include
-#include
-#include
-#include
-#include
-#ifdef MACOSX
+#include
+
+#if defined(_ALLBSD_SOURCE)
#include
#include
-#include /* gethostname */
#endif
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
-#ifndef IPV6_DEFS_H
-#include
-#endif
#include "java_net_Inet4AddressImpl.h"
#include "java_net_Inet6AddressImpl.h"
@@ -80,7 +72,7 @@
hostname[NI_MAXHOST] = '\0';
}
-#if defined(__solaris__) && defined(AF_INET6)
+#if defined(__solaris__)
if (ret == 0) {
/* Solaris doesn't want to give us a fully qualified domain name.
* We do a reverse lookup to try and get one. This works
@@ -259,9 +251,7 @@
int retLen = 0;
int getaddrinfo_error=0;
-#ifdef AF_INET6
struct addrinfo hints, *res, *resNew = NULL;
-#endif /* AF_INET6 */
initInetAddressIDs(env);
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
@@ -273,7 +263,6 @@
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
CHECK_NULL_RETURN(hostname, NULL);
-#ifdef AF_INET6
/* Try once, with our static buffer. */
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
@@ -467,7 +456,6 @@
}
freeaddrinfo(res);
-#endif /* AF_INET6 */
return ret;
}
@@ -483,7 +471,6 @@
jstring ret = NULL;
-#ifdef AF_INET6
char host[NI_MAXHOST+1];
int error = 0;
int len = 0;
@@ -504,30 +491,28 @@
addr |= ((caddr[2] <<8) & 0xff00);
addr |= (caddr[3] & 0xff);
memset((void *) &him4, 0, sizeof(him4));
- him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+ him4.sin_addr.s_addr = htonl(addr);
him4.sin_family = AF_INET;
- sa = (struct sockaddr *) &him4;
+ sa = (struct sockaddr *)&him4;
len = sizeof(him4);
} else {
/*
* For IPv6 address construct a sockaddr_in6 structure.
*/
(*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
- memset((void *) &him6, 0, sizeof(him6));
- memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
+ memset((void *)&him6, 0, sizeof(him6));
+ memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr));
him6.sin6_family = AF_INET6;
- sa = (struct sockaddr *) &him6 ;
- len = sizeof(him6) ;
+ sa = (struct sockaddr *)&him6;
+ len = sizeof(him6);
}
- error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
- NI_NAMEREQD);
+ error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
if (!error) {
ret = (*env)->NewStringUTF(env, host);
CHECK_NULL_RETURN(ret, NULL);
}
-#endif /* AF_INET6 */
if (ret == NULL) {
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
@@ -542,7 +527,6 @@
fcntl(fd, F_SETFL, flags); \
}
-#ifdef AF_INET6
static jboolean
ping6(JNIEnv *env, jint fd, struct sockaddr_in6* him, jint timeout,
struct sockaddr_in6* netif, jint ttl) {
@@ -649,7 +633,6 @@
close(fd);
return JNI_FALSE;
}
-#endif /* AF_INET6 */
/*
* Class: java_net_Inet6AddressImpl
@@ -663,7 +646,6 @@
jint timeout,
jbyteArray ifArray,
jint ttl, jint if_scope) {
-#ifdef AF_INET6
jbyte caddr[16];
jint fd, sz;
struct sockaddr_in6 him6;
@@ -812,7 +794,4 @@
close(fd);
return JNI_FALSE;
}
-#else /* AF_INET6 */
- return JNI_FALSE;
-#endif /* AF_INET6 */
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/InetAddressImplFactory.c
--- a/jdk/src/java.base/unix/native/libnet/InetAddressImplFactory.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/InetAddressImplFactory.c Fri Nov 11 16:44:36 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,14 +37,10 @@
* Signature: ()I
*/
JNIEXPORT jboolean JNICALL
-Java_java_net_InetAddressImplFactory_isIPv6Supported(JNIEnv *env, jclass cls)
-{
-#ifdef AF_INET6
+Java_java_net_InetAddressImplFactory_isIPv6Supported(JNIEnv *env, jclass cls) {
if (ipv6_available()) {
return JNI_TRUE;
- } else
-#endif /* AF_INET6 */
- {
- return JNI_FALSE;
- }
+ } else {
+ return JNI_FALSE;
+ }
}
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/NetworkInterface.c
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,55 +22,36 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
#include
-
-#if defined(__solaris__)
-#include
-#include
-#include
-#include
-#endif
-
-#if defined(__linux__)
+#include
+#include
#include
-#include
-#include
-#endif
#if defined(_AIX)
-#include
#include
#include
#include
#endif
-#if defined(_ALLBSD_SOURCE)
-#include
-#include
+#if defined(__solaris__)
+#include
+#include
#include
-#if defined(__APPLE__)
+#endif
+
+#if defined(_ALLBSD_SOURCE)
#include
-#include
#include
-#include
#include
#endif
-#endif
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
+#include "java_net_InetAddress.h"
+
#if defined(__linux__)
#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
#elif defined(__solaris__)
@@ -145,10 +126,7 @@
static netif *enumInterfaces(JNIEnv *env);
static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs);
-
-#if defined(AF_INET6)
static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
-#endif
static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
struct sockaddr *ifr_addrP,
@@ -331,11 +309,8 @@
(JNIEnv *env, jclass cls, jobject iaObj)
{
netif *ifs, *curr;
-#if defined(AF_INET6)
- int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
-#else
- int family = AF_INET;
-#endif
+ int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ?
+ AF_INET : AF_INET6;
jobject obj = NULL;
jboolean match = JNI_FALSE;
@@ -361,9 +336,7 @@
match = JNI_TRUE;
break;
}
- }
-#if defined(AF_INET6)
- if (family == AF_INET6) {
+ } else if (family == AF_INET6) {
jbyte *bytes = (jbyte *)&(
((struct sockaddr_in6*)addrP->addr)->sin6_addr);
jbyte caddr[16];
@@ -381,7 +354,6 @@
break;
}
}
-#endif
}
if (match) {
@@ -725,7 +697,6 @@
return NULL;
}
}
-#if defined(AF_INET6)
if (addrP->family == AF_INET6) {
int scope=0;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
@@ -754,7 +725,6 @@
return NULL;
}
}
-#endif
(*env)->SetObjectArrayElement(env, addrArr, addr_index++, iaObj);
addrP = addrP->next;
@@ -815,25 +785,23 @@
}
// If IPv6 is available then enumerate IPv6 addresses.
-#if defined(AF_INET6)
- // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
- // so we have to call ipv6_available()
- if (ipv6_available()) {
- sock = openSocket(env, AF_INET6);
- if (sock < 0 && (*env)->ExceptionOccurred(env)) {
- freeif(ifs);
- return NULL;
- }
+ // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
+ // so we have to call ipv6_available()
+ if (ipv6_available()) {
+ sock = openSocket(env, AF_INET6);
+ if (sock < 0 && (*env)->ExceptionOccurred(env)) {
+ freeif(ifs);
+ return NULL;
+ }
- ifs = enumIPv6Interfaces(env, sock, ifs);
- close(sock);
+ ifs = enumIPv6Interfaces(env, sock, ifs);
+ close(sock);
- if ((*env)->ExceptionOccurred(env)) {
- freeif(ifs);
- return NULL;
- }
+ if ((*env)->ExceptionOccurred(env)) {
+ freeif(ifs);
+ return NULL;
}
-#endif
+ }
return ifs;
}
@@ -889,12 +857,8 @@
// Allocate for addr and brdcast at once
-#if defined(AF_INET6)
addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in)
: sizeof(struct sockaddr_in6);
-#else
- addr_size = sizeof(struct sockaddr_in);
-#endif
CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr) + 2 * addr_size);
addrP->addr = (struct sockaddr *)((char *)addrP + sizeof(netaddr));
@@ -1083,7 +1047,6 @@
/** Linux **/
#if defined(__linux__)
-#if defined(AF_INET6)
/*
* Opens a socket for further ioctl calls. Tries AF_INET socket first and
* if it fails return AF_INET6 socket.
@@ -1109,11 +1072,6 @@
// IPv6 socket regardless of type of address of an interface.
return sock;
}
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
- return openSocket(env, AF_INET);
-}
-#endif
/*
* Enumerates and returns all IPv4 interfaces on Linux.
@@ -1197,8 +1155,6 @@
return ifs;
}
-#if defined(AF_INET6)
-
/*
* Enumerates and returns all IPv6 interfaces on Linux.
*/
@@ -1240,8 +1196,6 @@
return ifs;
}
-#endif /* AF_INET6 */
-
/*
* Try to get the interface index.
*/
@@ -1330,7 +1284,6 @@
/** AIX **/
#if defined(_AIX)
-#if defined(AF_INET6)
/*
* Opens a socket for further ioctl calls. Tries AF_INET socket first and
* if it fails return AF_INET6 socket.
@@ -1354,11 +1307,6 @@
return sock;
}
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
- return openSocket(env, AF_INET);
-}
-#endif
/*
* Enumerates and returns all IPv4 interfaces on AIX.
@@ -1442,8 +1390,6 @@
return ifs;
}
-#if defined(AF_INET6)
-
/*
* Enumerates and returns all IPv6 interfaces on AIX.
*/
@@ -1518,8 +1464,6 @@
return ifs;
}
-#endif /* AF_INET6 */
-
/*
* Try to get the interface index.
*/
@@ -1614,7 +1558,6 @@
/** Solaris **/
#if defined(__solaris__)
-#if defined(AF_INET6)
/*
* Opens a socket for further ioctl calls. Tries AF_INET socket first and
* if it fails return AF_INET6 socket.
@@ -1659,11 +1602,6 @@
return sock;
}
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
- return openSocket(env, AF_INET);
-}
-#endif
/*
* Enumerates and returns all IPv4 interfaces on Solaris.
@@ -1739,8 +1677,6 @@
return ifs;
}
-#if defined(AF_INET6)
-
/*
* Enumerates and returns all IPv6 interfaces on Solaris.
*/
@@ -1803,8 +1739,6 @@
return ifs;
}
-#endif /* AF_INET6 */
-
/*
* Try to get the interface index.
* (Not supported on Solaris 2.6 or 7)
@@ -1976,7 +1910,6 @@
/** BSD **/
#if defined(_ALLBSD_SOURCE)
-#if defined(AF_INET6)
/*
* Opens a socket for further ioctl calls. Tries AF_INET socket first and
* if it fails return AF_INET6 socket.
@@ -2000,11 +1933,6 @@
return sock;
}
-#else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
- return openSocket(env, AF_INET);
-}
-#endif
/*
* Enumerates and returns all IPv4 interfaces on BSD.
@@ -2050,8 +1978,6 @@
return ifs;
}
-#if defined(AF_INET6)
-
/*
* Enumerates and returns all IPv6 interfaces on BSD.
*/
@@ -2092,8 +2018,6 @@
return ifs;
}
-#endif /* AF_INET6 */
-
/*
* Try to get the interface index.
*/
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,29 +22,23 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
#include
-#include
#include
#include
-#include
-#include
+#include
-#ifdef __solaris__
-#include
-#include
-#include
+#if defined(__solaris__)
+#include
+#endif
-#ifndef BSD_COMP
-#define BSD_COMP
-#endif
-#endif
+#include "net_util.h"
+
+#include "java_net_PlainDatagramSocketImpl.h"
+#include "java_net_InetAddress.h"
+#include "java_net_NetworkInterface.h"
+#include "java_net_SocketOptions.h"
+
#ifdef __linux__
-#include
-#include
-#include
-#include
-
#define IPV6_MULTICAST_IF 17
#ifndef SO_BSDCOMPAT
#define SO_BSDCOMPAT 14
@@ -58,7 +52,11 @@
#endif
#endif // __linux__
-#include
+#ifdef __solaris__
+#ifndef BSD_COMP
+#define BSD_COMP
+#endif
+#endif
#ifndef IPTOS_TOS_MASK
#define IPTOS_TOS_MASK 0x1e
@@ -67,12 +65,6 @@
#define IPTOS_PREC_MASK 0xe0
#endif
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-#include "java_net_SocketOptions.h"
-#include "java_net_PlainDatagramSocketImpl.h"
-#include "java_net_NetworkInterface.h"
/************************************************************************
* PlainDatagramSocketImpl
*/
@@ -151,9 +143,6 @@
JNIEXPORT void JNICALL
Java_java_net_PlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
-#ifdef __linux__
- struct utsname sysinfo;
-#endif
pdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
"Ljava/io/FileDescriptor;");
CHECK_NULL(pdsi_fdID);
@@ -310,13 +299,10 @@
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
memset(&addr, 0, sizeof(addr));
-#ifdef AF_INET6
if (ipv6_available()) {
addr.sa6.sin6_family = AF_UNSPEC;
len = sizeof(struct sockaddr_in6);
- } else
-#endif
- {
+ } else {
addr.sa4.sin_family = AF_UNSPEC;
len = sizeof(struct sockaddr_in);
}
@@ -330,12 +316,9 @@
localPort = NET_GetPortFromSockaddr(&addr.sa);
if (localPort == 0) {
localPort = (*env)->GetIntField(env, this, pdsi_localPortID);
-#ifdef AF_INET6
if (addr.sa.sa_family == AF_INET6) {
addr.sa6.sin6_port = htons(localPort);
- } else
-#endif /* AF_INET6 */
- {
+ } else {
addr.sa4.sin_port = htons(localPort);
}
@@ -443,12 +426,9 @@
(*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
(jbyte *)fullPacket);
-#ifdef AF_INET6
if (trafficClass != 0 && ipv6_available()) {
NET_SetTrafficClass(&rmtaddr.sa, trafficClass);
}
-#endif /* AF_INET6 */
-
/*
* Send the datagram.
@@ -549,11 +529,8 @@
}
iaObj = NET_SockaddrToInetAddress(env, &rmtaddr.sa, &port);
-#ifdef AF_INET6
- family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
-#else
- family = AF_INET;
-#endif
+ family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+ AF_INET : AF_INET6;
if (family == AF_INET) { /* this API can't handle IPV6 addresses */
int address = getInetAddress_addr(env, iaObj);
setInetAddress_addr(env, addressObj, address);
@@ -918,11 +895,7 @@
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
int arg, fd, t = 1;
char tmpbuf[1024];
-#ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
- int domain = AF_INET;
-#endif
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
@@ -936,7 +909,6 @@
return;
}
-#ifdef AF_INET6
/* Disable IPV6_V6ONLY to ensure dual-socket support */
if (domain == AF_INET6) {
arg = 0;
@@ -947,7 +919,6 @@
return;
}
}
-#endif /* AF_INET6 */
#ifdef __APPLE__
arg = 65507;
@@ -987,7 +958,7 @@
}
#endif
-#if defined (__linux__) && defined (AF_INET6)
+#if defined (__linux__)
/*
* On Linux for IPv6 sockets we must set the hop limit
* to 1 to be compatible with default TTL of 1 for IPv4 sockets.
@@ -1071,7 +1042,7 @@
*/
for (i = 0; i < len; i++) {
addr = (*env)->GetObjectArrayElement(env, addrArray, i);
- if (getInetAddress_family(env, addr) == IPv4) {
+ if (getInetAddress_family(env, addr) == java_net_InetAddress_IPv4) {
in.s_addr = htonl(getInetAddress_addr(env, addr));
break;
}
@@ -1088,7 +1059,6 @@
* Set outgoing multicast interface designated by a NetworkInterface.
* Throw exception if failed.
*/
-#ifdef AF_INET6
static void mcast_set_if_by_if_v6(JNIEnv *env, jobject this, int fd, jobject value) {
static jfieldID ni_indexID;
int index;
@@ -1113,9 +1083,7 @@
}
return;
}
-
}
-#endif /* AF_INET6 */
/*
* Set outgoing multicast interface designated by an InetAddress.
@@ -1137,7 +1105,6 @@
* Set outgoing multicast interface designated by an InetAddress.
* Throw exception if failed.
*/
-#ifdef AF_INET6
static void mcast_set_if_by_addr_v6(JNIEnv *env, jobject this, int fd, jobject value) {
static jclass ni_class;
if (ni_class == NULL) {
@@ -1159,7 +1126,6 @@
mcast_set_if_by_if_v6(env, this, fd, value);
}
-#endif
/*
* Sets the multicast interface.
@@ -1191,7 +1157,6 @@
/*
* value is an InetAddress.
*/
-#ifdef AF_INET6
#ifdef __linux__
mcast_set_if_by_addr_v4(env, this, fd, value);
if (ipv6_available()) {
@@ -1207,16 +1172,12 @@
mcast_set_if_by_addr_v4(env, this, fd, value);
}
#endif /* __linux__ */
-#else
- mcast_set_if_by_addr_v4(env, this, fd, value);
-#endif /* AF_INET6 */
}
if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
/*
* value is a NetworkInterface.
*/
-#ifdef AF_INET6
#ifdef __linux__
mcast_set_if_by_if_v4(env, this, fd, value);
if (ipv6_available()) {
@@ -1232,9 +1193,6 @@
mcast_set_if_by_if_v4(env, this, fd, value);
}
#endif /* __linux__ */
-#else
- mcast_set_if_by_if_v4(env, this, fd, value);
-#endif /* AF_INET6 */
}
}
@@ -1266,7 +1224,6 @@
/*
* Enable/disable local loopback of multicast datagrams.
*/
-#ifdef AF_INET6
static void mcast_set_loop_v6(JNIEnv *env, jobject this, int fd, jobject value) {
jclass cls;
jfieldID fid;
@@ -1289,14 +1246,12 @@
}
}
-#endif /* AF_INET6 */
/*
* Sets the multicast loopback mode.
*/
static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
jint opt, jobject value) {
-#ifdef AF_INET6
#ifdef __linux__
mcast_set_loop_v4(env, this, fd, value);
if (ipv6_available()) {
@@ -1312,9 +1267,6 @@
mcast_set_loop_v4(env, this, fd, value);
}
#endif /* __linux__ */
-#else
- mcast_set_loop_v4(env, this, fd, value);
-#endif /* AF_INET6 */
}
/*
@@ -1456,11 +1408,9 @@
jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
jboolean isIPV4 = JNI_TRUE;
-#ifdef AF_INET6
if (ipv6_available()) {
isIPV4 = JNI_FALSE;
}
-#endif
/*
* IPv4 implementation
@@ -1559,7 +1509,6 @@
}
-#ifdef AF_INET6
/*
* IPv6 implementation
*/
@@ -1677,7 +1626,6 @@
}
return ni;
}
-#endif
return NULL;
}
@@ -1815,7 +1763,6 @@
/*
* Set hops limit for a socket. Throw exception if failed.
*/
-#ifdef AF_INET6
static void setHopLimit(JNIEnv *env, int fd, jint ttl) {
int ittl = (int)ttl;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
@@ -1824,7 +1771,6 @@
(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
}
}
-#endif
/*
* Class: java_net_PlainDatagramSocketImpl
@@ -1847,7 +1793,6 @@
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
/* setsockopt to be correct TTL */
-#ifdef AF_INET6
#ifdef __linux__
setTTL(env, fd, ttl);
JNU_CHECK_EXCEPTION(env);
@@ -1861,9 +1806,6 @@
setTTL(env, fd, ttl);
}
#endif /* __linux__ */
-#else
- setTTL(env, fd, ttl);
-#endif /* AF_INET6 */
}
/*
@@ -1896,7 +1838,6 @@
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
/* getsockopt of TTL */
-#ifdef AF_INET6
if (ipv6_available()) {
int ttl = 0;
socklen_t len = sizeof(ttl);
@@ -1908,19 +1849,17 @@
return -1;
}
return (jint)ttl;
- } else
-#endif /* AF_INET6 */
- {
- u_char ttl = 0;
- socklen_t len = sizeof(ttl);
- if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
- (char*)&ttl, &len) < 0) {
- JNU_ThrowByNameWithMessageAndLastError
- (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
- return -1;
- }
- return (jint)ttl;
+ } else {
+ u_char ttl = 0;
+ socklen_t len = sizeof(ttl);
+ if (getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
+ (char*)&ttl, &len) < 0) {
+ JNU_ThrowByNameWithMessageAndLastError
+ (env, JNU_JAVANETPKG "SocketException", "Error getting socket option");
+ return -1;
}
+ return (jint)ttl;
+ }
}
@@ -1966,22 +1905,14 @@
/*
* Determine if this is an IPv4 or IPv6 join/leave.
*/
-#ifdef AF_INET6
ipv6_join_leave = ipv6_available();
#ifdef __linux__
- if (getInetAddress_family(env, iaObj) == IPv4) {
+ if (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) {
ipv6_join_leave = JNI_FALSE;
}
#endif
-#else
- /*
- * IPv6 not compiled in
- */
- ipv6_join_leave = JNI_FALSE;
-#endif
-
/*
* For IPv4 join use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP socket option
*
@@ -2006,7 +1937,7 @@
* NetworkInterface
*/
if (niObj != NULL) {
-#if defined(__linux__) && defined(AF_INET6)
+#if defined(__linux__)
if (ipv6_available()) {
static jfieldID ni_indexID;
@@ -2062,7 +1993,7 @@
if (niObj == NULL) {
-#if defined(__linux__) && defined(AF_INET6)
+#if defined(__linux__)
if (ipv6_available()) {
int index;
@@ -2118,7 +2049,7 @@
* should return ENOPROTOOPT. We assume this will be fixed in Linux
* at some stage.
*/
-#if defined(__linux__) && defined(AF_INET6)
+#if defined(__linux__)
if (errno == ENOPROTOOPT) {
if (ipv6_available()) {
ipv6_join_leave = JNI_TRUE;
@@ -2155,14 +2086,14 @@
* IPv6 join. If it's an IPv4 multicast group then we use an IPv4-mapped
* address.
*/
-#ifdef AF_INET6
{
struct ipv6_mreq mname6;
jbyteArray ipaddress;
jbyte caddr[16];
jint family;
jint address;
- family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+ family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+ AF_INET : AF_INET6;
if (family == AF_INET) { /* will convert to IPv4-mapped address */
memset((char *) caddr, 0, 16);
address = getInetAddress_addr(env, iaObj);
@@ -2242,7 +2173,6 @@
}
}
}
-#endif
}
/*
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c
--- a/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,32 +22,8 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+#include
-#include
-#include
-#include
-#include
-#if defined(__linux__)
-#include
-#endif
-#include /* Defines TCP_NODELAY, needed for 2.6 */
-#include
-#ifdef __linux__
-#include
-#endif
-#include
-#include
-
-#ifdef __solaris__
-#include
-#endif
-#ifdef __linux__
-#include
-#include
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
#include "java_net_SocketOptions.h"
@@ -186,11 +162,7 @@
jobject fdObj, ssObj;
int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
-#ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
- int domain = AF_INET;
-#endif
if (socketExceptionCls == NULL) {
jclass c = (*env)->FindClass(env, "java/net/SocketException");
@@ -214,7 +186,6 @@
return;
}
-#ifdef AF_INET6
/* Disable IPV6_V6ONLY to ensure dual-socket support */
if (domain == AF_INET6) {
int arg = 0;
@@ -225,7 +196,6 @@
return;
}
}
-#endif /* AF_INET6 */
/*
* If this is a server socket then enable SO_REUSEADDR
@@ -295,11 +265,10 @@
}
setDefaultScopeID(env, &him.sa);
-#ifdef AF_INET6
if (trafficClass != 0 && ipv6_available()) {
NET_SetTrafficClass(&him.sa, trafficClass);
}
-#endif /* AF_INET6 */
+
if (timeout <= 0) {
connect_rv = NET_Connect(fd, &him.sa, len);
#ifdef __solaris__
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/SdpSupport.c
--- a/jdk/src/java.base/unix/native/libnet/SdpSupport.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/SdpSupport.c Fri Nov 11 16:44:36 2016 +0100
@@ -56,11 +56,7 @@
int s;
#if defined(__solaris__)
- #ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET;
- #else
- int domain = AF_INET;
- #endif
s = socket(domain, SOCK_STREAM, PROTO_SDP);
#elif defined(__linux__)
/**
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/SocketInputStream.c
--- a/jdk/src/java.base/unix/native/libnet/SocketInputStream.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/SocketInputStream.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,20 +22,15 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
-#include
#include
-#include
-#include
-#include "jvm.h"
-#include "jni_util.h"
#include "net_util.h"
#include "java_net_SocketInputStream.h"
-/************************************************************************
+/*
* SocketInputStream
*/
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/SocketOutputStream.c
--- a/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,15 +22,10 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
-#include
#include
-#include
-#include
-#include "jni_util.h"
-#include "jvm.h"
#include "net_util.h"
#include "java_net_SocketOutputStream.h"
diff -r f71b844f33d1 -r 95af45781076 jdk/src/java.base/unix/native/libnet/net_util_md.c
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Mon Nov 14 11:15:43 2016 +0100
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Fri Nov 11 16:44:36 2016 +0100
@@ -22,60 +22,42 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include
#include
+#include
+#include // defines TCP_NODELAY
+#include
#include
-#include
-#include
-#include /* Defines TCP_NODELAY, needed for 2.6 */
-#include
-#include
-#include
-#include
-#include
+#include
#include
-#ifndef _ALLBSD_SOURCE
-#include
-#else
-#include
-#include
-#include
-#include
-#ifndef MAXINT
-#define MAXINT INT_MAX
-#endif
-#endif
-
-#ifdef __solaris__
-#include