--- a/jdk/make/com/sun/java/pack/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/com/sun/java/pack/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -56,10 +56,6 @@
vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
-
-
-
-
ifeq ($(STANDALONE),true)
ZIPOBJDIR = $(OUTPUTDIR)/tmp/sun/java.util.zip/zip/$(OBJDIRNAME)
@@ -131,8 +127,9 @@
pack200-tool:
$(call make-launcher, pack200, com.sun.java.util.jar.pack.Driver, , --pack)
+# ignore mapfile for non-product binary
unpacker:
- $(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_OPT= LDMAPFLAGS_DBG=
+ $(MAKE) $(UNPACK_EXE) STANDALONE=true LDMAPFLAGS_DBG=
ifeq ($(PLATFORM), windows)
IMVERSIONVALUE=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)
@@ -147,8 +144,14 @@
$(ECHO) "Resource files not required for Unix"
endif
+# Mapfile-vers.gmk, does not copy over the mapfile-vers-unpack200, when
+# the make utiliy is re-invoked, as in this case. In order to workaround
+# this special case, the mapfile required for the unpack200 command, is
+# explicitly copied over to the expected location.
$(UNPACK_EXE): $(UNPACK_EXE_FILES_o) updatefiles winres
$(prep-target)
+ $(RM) $(TEMPDIR)/mapfile-vers
+ $(CP) mapfile-vers-unpack200 $(TEMPDIR)/mapfile-vers
$(LINKER) $(LDDFLAGS) $(UNPACK_EXE_FILES_o) $(RES) $(LIBCXX) $(LDOUTPUT)$(TEMPDIR)/unpack200$(EXE_SUFFIX)
ifdef MT
$(MT) /manifest $(OBJDIR)/unpack200$(EXE_SUFFIX).manifest /outputresource:$(TEMPDIR)/unpack200$(EXE_SUFFIX);#1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/com/sun/java/pack/mapfile-vers-unpack200 Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute 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.
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+ local:
+ *;
+};
--- a/jdk/make/common/Mapfile-vers.gmk Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/common/Mapfile-vers.gmk Tue Apr 12 14:23:03 2011 -0700
@@ -52,8 +52,8 @@
endif
# If we are re-ordering functions in this solaris library, we need to make
- # sure that -xF is added to the compile lines. This option is critical and
- # enables the functions to be reordered.
+ # sure that -xF is added to the compile lines. This option is critical and
+ # enables the functions to be reordered.
ifdef FILES_reorder
CFLAGS_OPT += -xF
CXXFLAGS_OPT += -xF
@@ -76,7 +76,6 @@
endif # PLATFORM
-
ifeq ($(PLATFORM), linux)
ifeq ($(VARIANT), OPT)
--- a/jdk/make/common/Program.gmk Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/common/Program.gmk Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
# 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,6 +55,11 @@
program: $(ACTUAL_PROGRAM)
+# reuse the mapfiles in the launcher's directory, the same should
+# be applicable to the tool launchers as well.
+FILES_m = $(BUILDDIR)/java/main/java/mapfile-$(ARCH)
+include $(BUILDDIR)/common/Mapfile-vers.gmk
+
include $(JDK_TOPDIR)/make/common/Rules.gmk
ifdef NEVER_ACT_AS_SERVER_CLASS_MACHINE
--- a/jdk/make/java/java/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/java/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -198,10 +198,12 @@
#
# What to link?
+# On Windows, shell32 is not normally required and so it is delay loaded.
#
ifeq ($(PLATFORM),windows)
OTHER_LDLIBS += $(JVMLIB) -libpath:$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) fdlibm.lib \
- -libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib
+ -libpath:$(OBJDIR)/../../../verify/$(OBJDIRNAME) verify.lib \
+ shell32.lib delayimp.lib /DELAYLOAD:shell32.dll
else
OTHER_LDLIBS += $(JVMLIB) -lverify $(LIBSOCKET) $(LIBNSL) -ldl \
-L$(OBJDIR)/../../../fdlibm/$(OBJDIRNAME) -lfdlibm.$(ARCH)
--- a/jdk/make/java/main/java/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/main/java/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -61,5 +61,4 @@
ifeq ($(PLATFORM), solaris)
LDFLAGS += -R$(OPENWIN_LIB)
-LDFLAGS += -M mapfile-$(ARCH)
endif
--- a/jdk/make/java/main/java/mapfile-amd64 Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/main/java/mapfile-amd64 Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
# interested in declaring a version, simply scoping the file is sufficient.
#
-{
+SUNWprivate_1.1 {
global:
main; # Provides basic adb symbol offsets
environ; # Public symbols and required by Java run time
--- a/jdk/make/java/main/java/mapfile-i586 Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/main/java/mapfile-i586 Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
# interested in declaring a version, simply scoping the file is sufficient.
#
-{
+SUNWprivate_1.1 {
global:
main; # Provides basic adb symbol offsets
environ; # Public symbols and required by Java run time
--- a/jdk/make/java/main/java/mapfile-sparc Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/main/java/mapfile-sparc Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
# interested in declaring a version, simply scoping the file is sufficient.
#
-{
+SUNWprivate_1.1 {
global:
main; # Provides basic adb symbol offsets
environ; # Public symbols and required by Java run time
--- a/jdk/make/java/main/java/mapfile-sparcv9 Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/main/java/mapfile-sparcv9 Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
# interested in declaring a version, simply scoping the file is sufficient.
#
-{
+SUNWprivate_1.1 {
global:
main; # Provides basic adb symbol offsets
environ; # Public symbols and required by Java run time
--- a/jdk/make/java/management/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/java/management/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -86,7 +86,8 @@
-I$(SHARE_SRC)/native/sun/management
ifeq ($(PLATFORM),windows)
- OTHER_LDLIBS += $(JVMLIB)
+ # Need process status helper API (psapi) on Windows
+ OTHER_LDLIBS += $(JVMLIB) psapi.lib
endif
#
--- a/jdk/make/mksample/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/mksample/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# 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 @@
endif
SUBDIRS =
-SUBDIRS_misc = nio scripting nbproject
+SUBDIRS_misc = nio scripting nbproject forkjoin
SUBDIRS_enterprise = $(WEBSERVICES_SUBDIR)
SUBDIRS_management = jmx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mksample/forkjoin/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for building all the samples under the forkjoin subdirectory.
+#
+
+BUILDDIR = ../..
+PRODUCT = java
+include $(BUILDDIR)/common/Defs.gmk
+
+SUBDIRS = mergesort
+include $(BUILDDIR)/common/Subdirs.gmk
+
+all build clean clobber::
+ $(SUBDIRS-loop)
+
+clobber clean ::
+ $(RM) -r $(SAMPLEDIR)/forkjoin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mksample/forkjoin/mergesort/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for the forkjoin/mergesort sample code
+#
+
+BUILDDIR = ../../..
+
+PRODUCT = java
+
+include $(BUILDDIR)/common/Defs.gmk
+
+SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/forkjoin/mergesort
+SAMPLE_DST_DIR = $(SAMPLEDIR)/forkjoin/mergesort
+
+SAMPLE_FILES = \
+ $(SAMPLE_DST_DIR)/MergeDemo.java \
+ $(SAMPLE_DST_DIR)/MergeSort.java
+
+all build: $(SAMPLE_FILES)
+
+$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/%
+ $(install-file)
+
+clean clobber:
+ $(RM) -r $(SAMPLE_DST_DIR)
+
+.PHONY: all build clean clobber
--- a/jdk/make/mksample/nio/Makefile Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/make/mksample/nio/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
# 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 @@
PRODUCT = java
include $(BUILDDIR)/common/Defs.gmk
-SUBDIRS = file multicast server
+SUBDIRS = chatserver file multicast server
include $(BUILDDIR)/common/Subdirs.gmk
all build clean clobber::
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mksample/nio/chatserver/Makefile Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+#
+# Makefile for the nio/chatserver sample code
+#
+
+BUILDDIR = ../../..
+
+PRODUCT = java
+
+include $(BUILDDIR)/common/Defs.gmk
+
+SAMPLE_SRC_DIR = $(SHARE_SRC)/sample/nio/chatserver
+SAMPLE_DST_DIR = $(SAMPLEDIR)/nio/chatserver
+
+SAMPLE_FILES = \
+ $(SAMPLE_DST_DIR)/ChatServer.java \
+ $(SAMPLE_DST_DIR)/Client.java \
+ $(SAMPLE_DST_DIR)/ClientReader.java \
+ $(SAMPLE_DST_DIR)/DataReader.java \
+ $(SAMPLE_DST_DIR)/MessageReader.java \
+ $(SAMPLE_DST_DIR)/NameReader.java \
+ $(SAMPLE_DST_DIR)/README.txt
+
+all build: $(SAMPLE_FILES)
+
+$(SAMPLE_DST_DIR)/%: $(SAMPLE_SRC_DIR)/%
+ $(install-file)
+
+clean clobber:
+ $(RM) -r $(SAMPLE_DST_DIR)
+
+.PHONY: all build clean clobber
--- a/jdk/src/share/bin/jli_util.h Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/bin/jli_util.h Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
void JLI_MemFree(void *ptr);
int JLI_StrCCmp(const char *s1, const char* s2);
-
#define JLI_StrLen(p1) strlen((p1))
#define JLI_StrChr(p1, p2) strchr((p1), (p2))
#define JLI_StrRChr(p1, p2) strrchr((p1), (p2))
@@ -48,6 +47,7 @@
#define JLI_StrSpn(p1, p2) strspn((p1), (p2))
#define JLI_StrCSpn(p1, p2) strcspn((p1), (p2))
#define JLI_StrPBrk(p1, p2) strpbrk((p1), (p2))
+#define JLI_StrTok(p1, p2) strtok((p1), (p2))
/* On Windows lseek() is in io.h rather than the location dictated by POSIX. */
#ifdef _WIN32
--- a/jdk/src/share/classes/java/lang/Character.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/lang/Character.java Tue Apr 12 14:23:03 2011 -0700
@@ -4184,9 +4184,11 @@
aliases.put("AVST", AVESTAN);
aliases.put("BALI", BALINESE);
aliases.put("BAMU", BAMUM);
+ aliases.put("BATK", BATAK);
aliases.put("BENG", BENGALI);
aliases.put("BOPO", BOPOMOFO);
aliases.put("BRAI", BRAILLE);
+ aliases.put("BRAH", BRAHMI);
aliases.put("BUGI", BUGINESE);
aliases.put("BUHD", BUHID);
aliases.put("CANS", CANADIAN_ABORIGINAL);
@@ -4230,6 +4232,7 @@
aliases.put("LISU", LISU);
aliases.put("LYCI", LYCIAN);
aliases.put("LYDI", LYDIAN);
+ aliases.put("MAND", MANDAIC);
aliases.put("MLYM", MALAYALAM);
aliases.put("MONG", MONGOLIAN);
aliases.put("MTEI", MEETEI_MAYEK);
--- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Tue Apr 12 14:23:03 2011 -0700
@@ -26,6 +26,7 @@
package java.lang.reflect;
import java.security.AccessController;
+import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
import java.lang.annotation.Annotation;
@@ -201,4 +202,73 @@
public Annotation[] getDeclaredAnnotations() {
throw new AssertionError("All subclasses should override this method");
}
+
+
+ // Shared access checking logic.
+
+ // For non-public members or members in package-private classes,
+ // it is necessary to perform somewhat expensive security checks.
+ // If the security check succeeds for a given class, it will
+ // always succeed (it is not affected by the granting or revoking
+ // of permissions); we speed up the check in the common case by
+ // remembering the last Class for which the check succeeded.
+ //
+ // The simple security check for Constructor is to see if
+ // the caller has already been seen, verified, and cached.
+ // (See also Class.newInstance(), which uses a similar method.)
+ //
+ // A more complicated security check cache is needed for Method and Field
+ // The cache can be either null (empty cache), a 2-array of {caller,target},
+ // or a caller (with target implicitly equal to this.clazz).
+ // In the 2-array case, the target is always different from the clazz.
+ volatile Object securityCheckCache;
+
+ void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ throws IllegalAccessException
+ {
+ if (caller == clazz) { // quick check
+ return; // ACCESS IS OK
+ }
+ Object cache = securityCheckCache; // read volatile
+ Class<?> targetClass = clazz;
+ if (obj != null
+ && Modifier.isProtected(modifiers)
+ && ((targetClass = obj.getClass()) != clazz)) {
+ // Must match a 2-list of { caller, targetClass }.
+ if (cache instanceof Class[]) {
+ Class<?>[] cache2 = (Class<?>[]) cache;
+ if (cache2[1] == targetClass &&
+ cache2[0] == caller) {
+ return; // ACCESS IS OK
+ }
+ // (Test cache[1] first since range check for [1]
+ // subsumes range check for [0].)
+ }
+ } else if (cache == caller) {
+ // Non-protected case (or obj.class == this.clazz).
+ return; // ACCESS IS OK
+ }
+
+ // If no return, fall through to the slow path.
+ slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ }
+
+ // Keep all this slow stuff out of line:
+ void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
+ Class<?> targetClass)
+ throws IllegalAccessException
+ {
+ Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+
+ // Success: Update the cache.
+ Object cache = ((targetClass == clazz)
+ ? caller
+ : new Class<?>[] { caller, targetClass });
+
+ // Note: The two cache elements are not volatile,
+ // but they are effectively final. The Java memory model
+ // guarantees that the initializing stores for the cache
+ // elements will occur before the volatile write.
+ securityCheckCache = cache; // write volatile
+ }
}
--- a/jdk/src/share/classes/java/lang/reflect/Constructor.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java Tue Apr 12 14:23:03 2011 -0700
@@ -74,14 +74,6 @@
private byte[] annotations;
private byte[] parameterAnnotations;
- // For non-public members or members in package-private classes,
- // it is necessary to perform somewhat expensive security checks.
- // If the security check succeeds for a given class, it will
- // always succeed (it is not affected by the granting or revoking
- // of permissions); we speed up the check in the common case by
- // remembering the last Class for which the check succeeded.
- private volatile Class<?> securityCheckCache;
-
// Generics infrastructure
// Accessor for factory
private GenericsFactory getFactory() {
@@ -495,7 +487,7 @@
* this object represents
*
* @exception IllegalAccessException if this {@code Constructor} object
- * enforces Java language access control and the underlying
+ * is enforcing Java language access control and the underlying
* constructor is inaccessible.
* @exception IllegalArgumentException if the number of actual
* and formal parameters differ; if an unwrapping
@@ -518,16 +510,17 @@
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(2);
- if (securityCheckCache != caller) {
- Reflection.ensureMemberAccess(caller, clazz, null, modifiers);
- securityCheckCache = caller;
- }
+
+ checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
- if (constructorAccessor == null) acquireConstructorAccessor();
- return (T) constructorAccessor.newInstance(initargs);
+ ConstructorAccessor ca = constructorAccessor; // read volatile
+ if (ca == null) {
+ ca = acquireConstructorAccessor();
+ }
+ return (T) ca.newInstance(initargs);
}
/**
@@ -560,18 +553,20 @@
// ConstructorAccessor for a given Constructor. However, avoiding
// synchronization will probably make the implementation more
// scalable.
- private void acquireConstructorAccessor() {
+ private ConstructorAccessor acquireConstructorAccessor() {
// First check to see if one has been created yet, and take it
// if so.
ConstructorAccessor tmp = null;
if (root != null) tmp = root.getConstructorAccessor();
if (tmp != null) {
constructorAccessor = tmp;
- return;
+ } else {
+ // Otherwise fabricate one and propagate it up to the root
+ tmp = reflectionFactory.newConstructorAccessor(this);
+ setConstructorAccessor(tmp);
}
- // Otherwise fabricate one and propagate it up to the root
- tmp = reflectionFactory.newConstructorAccessor(this);
- setConstructorAccessor(tmp);
+
+ return tmp;
}
// Returns ConstructorAccessor for this Constructor object, not
--- a/jdk/src/share/classes/java/lang/reflect/Field.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java Tue Apr 12 14:23:03 2011 -0700
@@ -79,11 +79,6 @@
// potentially many Field objects pointing to it.)
private Field root;
- // More complicated security check cache needed here than for
- // Class.newInstance() and Constructor.newInstance()
- private Class<?> securityCheckCache;
- private Class<?> securityCheckTargetClassCache;
-
// Generics infrastructure
private String getGenericSignature() {return signature;}
@@ -340,7 +335,7 @@
* instance of the class or interface declaring the underlying
* field, the method throws an {@code IllegalArgumentException}.
*
- * <p>If this {@code Field} object enforces Java language access control, and
+ * <p>If this {@code Field} object is enforcing Java language access control, and
* the underlying field is inaccessible, the method throws an
* {@code IllegalAccessException}.
* If the underlying field is static, the class that declared the
@@ -360,8 +355,9 @@
* {@code obj}; primitive values are wrapped in an appropriate
* object before being returned
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof).
@@ -383,8 +379,9 @@
* from
* @return the value of the {@code boolean} field
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -410,8 +407,9 @@
* from
* @return the value of the {@code byte} field
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -439,8 +437,9 @@
* from
* @return the value of the field converted to type {@code char}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -468,8 +467,9 @@
* from
* @return the value of the field converted to type {@code short}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -497,8 +497,9 @@
* from
* @return the value of the field converted to type {@code int}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -526,8 +527,9 @@
* from
* @return the value of the field converted to type {@code long}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -555,8 +557,9 @@
* from
* @return the value of the field converted to type {@code float}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -584,8 +587,9 @@
* from
* @return the value of the field converted to type {@code double}
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is inaccessible.
* @exception IllegalArgumentException if the specified object is not
* an instance of the class or interface declaring the
* underlying field (or a subclass or implementor
@@ -621,14 +625,14 @@
* an instance of the class or interface declaring the underlying
* field, the method throws an {@code IllegalArgumentException}.
*
- * <p>If this {@code Field} object enforces Java language access control, and
+ * <p>If this {@code Field} object is enforcing Java language access control, and
* the underlying field is inaccessible, the method throws an
* {@code IllegalAccessException}.
*
* <p>If the underlying field is final, the method throws an
- * {@code IllegalAccessException} unless
- * {@code setAccessible(true)} has succeeded for this field
- * and this field is non-static. Setting a final field in this way
+ * {@code IllegalAccessException} unless {@code setAccessible(true)}
+ * has succeeded for this {@code Field} object
+ * and the field is non-static. Setting a final field in this way
* is meaningful only during deserialization or reconstruction of
* instances of classes with blank final fields, before they are
* made available for access by other parts of a program. Use in
@@ -658,8 +662,9 @@
* @param value the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -686,8 +691,9 @@
* @param z the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -715,8 +721,9 @@
* @param b the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -744,8 +751,9 @@
* @param c the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -773,8 +781,9 @@
* @param s the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -802,8 +811,9 @@
* @param i the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -831,8 +841,9 @@
* @param l the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -860,8 +871,9 @@
* @param f the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -889,8 +901,9 @@
* @param d the new value for the field of {@code obj}
* being modified
*
- * @exception IllegalAccessException if the underlying field
- * is inaccessible.
+ * @exception IllegalAccessException if this {@code Field} object
+ * is enforcing Java language access control and the underlying
+ * field is either inaccessible or final.
* @exception IllegalArgumentException if the specified object is not an
* instance of the class or interface declaring the underlying
* field (or a subclass or implementor thereof),
@@ -936,6 +949,7 @@
tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
setFieldAccessor(tmp, overrideFinalCheck);
}
+
return tmp;
}
@@ -965,21 +979,8 @@
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(4);
- Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers))
- ? clazz
- : obj.getClass());
- synchronized (this) {
- if ((securityCheckCache == caller)
- && (securityCheckTargetClassCache == targetClass)) {
- return;
- }
- }
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
- synchronized (this) {
- securityCheckCache = caller;
- securityCheckTargetClassCache = targetClass;
- }
+ checkAccess(caller, clazz, obj, modifiers);
}
}
}
--- a/jdk/src/share/classes/java/lang/reflect/Method.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Method.java Tue Apr 12 14:23:03 2011 -0700
@@ -83,11 +83,6 @@
// potentially many Method objects pointing to it.)
private Method root;
- // More complicated security check cache needed here than for
- // Class.newInstance() and Constructor.newInstance()
- private Class<?> securityCheckCache;
- private Class<?> securityCheckTargetClassCache;
-
// Generics infrastructure
private String getGenericSignature() {return signature;}
@@ -402,28 +397,28 @@
*/
public String toString() {
try {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
int mod = getModifiers() & Modifier.methodModifiers();
if (mod != 0) {
- sb.append(Modifier.toString(mod) + " ");
+ sb.append(Modifier.toString(mod)).append(' ');
}
- sb.append(Field.getTypeName(getReturnType()) + " ");
- sb.append(Field.getTypeName(getDeclaringClass()) + ".");
- sb.append(getName() + "(");
+ sb.append(Field.getTypeName(getReturnType())).append(' ');
+ sb.append(Field.getTypeName(getDeclaringClass())).append('.');
+ sb.append(getName()).append('(');
Class<?>[] params = parameterTypes; // avoid clone
for (int j = 0; j < params.length; j++) {
sb.append(Field.getTypeName(params[j]));
if (j < (params.length - 1))
- sb.append(",");
+ sb.append(',');
}
- sb.append(")");
+ sb.append(')');
Class<?>[] exceptions = exceptionTypes; // avoid clone
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(exceptions[k].getName());
if (k < (exceptions.length - 1))
- sb.append(",");
+ sb.append(',');
}
}
return sb.toString();
@@ -475,15 +470,15 @@
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & Modifier.methodModifiers();
if (mod != 0) {
- sb.append(Modifier.toString(mod) + " ");
+ sb.append(Modifier.toString(mod)).append(' ');
}
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
- sb.append("<");
+ sb.append('<');
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
- sb.append(",");
+ sb.append(',');
// Class objects can't occur here; no need to test
// and call Class.getName().
sb.append(typeparm.toString());
@@ -494,10 +489,11 @@
Type genRetType = getGenericReturnType();
sb.append( ((genRetType instanceof Class<?>)?
- Field.getTypeName((Class<?>)genRetType):genRetType.toString()) + " ");
+ Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
+ .append(' ');
- sb.append(Field.getTypeName(getDeclaringClass()) + ".");
- sb.append(getName() + "(");
+ sb.append(Field.getTypeName(getDeclaringClass())).append('.');
+ sb.append(getName()).append('(');
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = (params[j] instanceof Class)?
@@ -507,9 +503,9 @@
param = param.replaceFirst("\\[\\]$", "...");
sb.append(param);
if (j < (params.length - 1))
- sb.append(",");
+ sb.append(',');
}
- sb.append(")");
+ sb.append(')');
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
@@ -518,7 +514,7 @@
((Class)exceptions[k]).getName():
exceptions[k].toString());
if (k < (exceptions.length - 1))
- sb.append(",");
+ sb.append(',');
}
}
return sb.toString();
@@ -565,7 +561,7 @@
* {@code args}
*
* @exception IllegalAccessException if this {@code Method} object
- * enforces Java language access control and the underlying
+ * is enforcing Java language access control and the underlying
* method is inaccessible.
* @exception IllegalArgumentException if the method is an
* instance method and the specified object argument
@@ -591,26 +587,15 @@
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(1);
- Class<?> targetClass = ((obj == null || !Modifier.isProtected(modifiers))
- ? clazz
- : obj.getClass());
- boolean cached;
- synchronized (this) {
- cached = (securityCheckCache == caller)
- && (securityCheckTargetClassCache == targetClass);
- }
- if (!cached) {
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
- synchronized (this) {
- securityCheckCache = caller;
- securityCheckTargetClassCache = targetClass;
- }
- }
+ checkAccess(caller, clazz, obj, modifiers);
}
}
- if (methodAccessor == null) acquireMethodAccessor();
- return methodAccessor.invoke(obj, args);
+ MethodAccessor ma = methodAccessor; // read volatile
+ if (ma == null) {
+ ma = acquireMethodAccessor();
+ }
+ return ma.invoke(obj, args);
}
/**
@@ -654,18 +639,20 @@
// (though not efficient) to generate more than one MethodAccessor
// for a given Method. However, avoiding synchronization will
// probably make the implementation more scalable.
- private void acquireMethodAccessor() {
+ private MethodAccessor acquireMethodAccessor() {
// First check to see if one has been created yet, and take it
// if so
MethodAccessor tmp = null;
if (root != null) tmp = root.getMethodAccessor();
if (tmp != null) {
methodAccessor = tmp;
- return;
+ } else {
+ // Otherwise fabricate one and propagate it up to the root
+ tmp = reflectionFactory.newMethodAccessor(this);
+ setMethodAccessor(tmp);
}
- // Otherwise fabricate one and propagate it up to the root
- tmp = reflectionFactory.newMethodAccessor(this);
- setMethodAccessor(tmp);
+
+ return tmp;
}
// Returns MethodAccessor for this Method object, not looking up
--- a/jdk/src/share/classes/java/nio/file/Files.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Files.java Tue Apr 12 14:23:03 2011 -0700
@@ -2067,7 +2067,7 @@
*
* @return {@code true} if the file is a symbolic link; {@code false} if
* the file does not exist, is not a symbolic link, or it cannot
- * be determined if the file is symbolic link or not.
+ * be determined if the file is a symbolic link or not.
*
* @throws SecurityException
* In the case of the default provider, and a security manager is
@@ -2106,7 +2106,7 @@
*
* @return {@code true} if the file is a directory; {@code false} if
* the file does not exist, is not a directory, or it cannot
- * be determined if the file is directory or not.
+ * be determined if the file is a directory or not.
*
* @throws SecurityException
* In the case of the default provider, and a security manager is
@@ -2142,8 +2142,8 @@
* options indicating how symbolic links are handled
*
* @return {@code true} if the file is a regular file; {@code false} if
- * the file does not exist, is not a direcregular filetory, or it
- * cannot be determined if the file is regular file or not.
+ * the file does not exist, is not a regular file, or it
+ * cannot be determined if the file is a regular file or not.
*
* @throws SecurityException
* In the case of the default provider, and a security manager is
--- a/jdk/src/share/classes/java/nio/file/Path.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Path.java Tue Apr 12 14:23:03 2011 -0700
@@ -550,18 +550,21 @@
* <p> If this path is relative then its absolute path is first obtained,
* as if by invoking the {@link #toAbsolutePath toAbsolutePath} method.
*
- * <p> The {@code resolveLinks} parameter specifies if symbolic links
- * should be resolved. This parameter is ignored when symbolic links are
- * not supported. Where supported, and the parameter has the value {@code
- * true} then symbolic links are resolved to their final target. Where the
- * parameter has the value {@code false} then this method does not resolve
- * symbolic links. Some implementations allow special names such as
- * "{@code ..}" to refer to the parent directory. When deriving the <em>real
- * path</em>, and a "{@code ..}" (or equivalent) is preceded by a
- * non-"{@code ..}" name then an implementation will typically causes both
- * names to be removed. When not resolving symbolic links and the preceding
- * name is a symbolic link then the names are only removed if it guaranteed
- * that the resulting path will locate the same file as this path.
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled. By default, symbolic links are resolved to their final
+ * target. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is
+ * present then this method does not resolve symbolic links.
+ *
+ * Some implementations allow special names such as "{@code ..}" to refer to
+ * the parent directory. When deriving the <em>real path</em>, and a
+ * "{@code ..}" (or equivalent) is preceded by a non-"{@code ..}" name then
+ * an implementation will typically cause both names to be removed. When
+ * not resolving symbolic links and the preceding name is a symbolic link
+ * then the names are only removed if it guaranteed that the resulting path
+ * will locate the same file as this path.
+ *
+ * @param options
+ * options indicating how symbolic links are handled
*
* @return an absolute path represent the <em>real</em> path of the file
* located by this object
@@ -576,7 +579,7 @@
* checkPropertyAccess} method is invoked to check access to the
* system property {@code user.dir}
*/
- Path toRealPath(boolean resolveLinks) throws IOException;
+ Path toRealPath(LinkOption... options) throws IOException;
/**
* Returns a {@link File} object representing this path. Where this {@code
--- a/jdk/src/share/classes/java/sql/DriverManager.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/sql/DriverManager.java Tue Apr 12 14:23:03 2011 -0700
@@ -80,7 +80,7 @@
// List of registered JDBC drivers
- private final static CopyOnWriteArrayList<Driver> registeredDrivers = new CopyOnWriteArrayList<Driver>();
+ private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();
private static volatile int loginTimeout = 0;
private static volatile java.io.PrintWriter logWriter = null;
private static volatile java.io.PrintStream logStream = null;
@@ -265,22 +265,22 @@
// Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL.
- for (Driver aDriver : registeredDrivers) {
+ for (DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver, callerCL)) {
+ if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
- if(aDriver.acceptsURL(url)) {
+ if(aDriver.driver.acceptsURL(url)) {
// Success!
- println("getDriver returning " + aDriver.getClass().getName());
- return (aDriver);
+ println("getDriver returning " + aDriver.driver.getClass().getName());
+ return (aDriver.driver);
}
} catch(SQLException sqe) {
// Drop through and try the next driver.
}
} else {
- println(" skipping: " + aDriver.getClass().getName());
+ println(" skipping: " + aDriver.driver.getClass().getName());
}
}
@@ -305,7 +305,7 @@
/* Register the driver if it has not already been added to our list */
if(driver != null) {
- registeredDrivers.addIfAbsent(driver);
+ registeredDrivers.addIfAbsent(new DriverInfo(driver));
} else {
// This is for compatibility with the original DriverManager
throw new NullPointerException();
@@ -333,9 +333,10 @@
ClassLoader callerCL = DriverManager.getCallerClassLoader();
println("DriverManager.deregisterDriver: " + driver);
- if(registeredDrivers.contains(driver)) {
+ DriverInfo aDriver = new DriverInfo(driver);
+ if(registeredDrivers.contains(aDriver)) {
if (isDriverAllowed(driver, callerCL)) {
- registeredDrivers.remove(driver);
+ registeredDrivers.remove(aDriver);
} else {
// If the caller does not have permission to load the driver then
// throw a SecurityException.
@@ -363,11 +364,11 @@
ClassLoader callerCL = DriverManager.getCallerClassLoader();
// Walk through the loaded registeredDrivers.
- for(Driver aDriver : registeredDrivers) {
+ for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver, callerCL)) {
- result.addElement(aDriver);
+ if(isDriverAllowed(aDriver.driver, callerCL)) {
+ result.addElement(aDriver.driver);
} else {
println(" skipping: " + aDriver.getClass().getName());
}
@@ -482,8 +483,8 @@
private static void loadInitialDrivers() {
String drivers;
try {
- drivers = (String) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
return System.getProperty("jdbc.drivers");
}
});
@@ -495,8 +496,8 @@
// exposed as a java.sql.Driver.class service.
// ServiceLoader.load() replaces the sun.misc.Providers()
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator driversIterator = loadedDrivers.iterator();
@@ -569,16 +570,16 @@
// Remember the first exception that gets raised so we can reraise it.
SQLException reason = null;
- for(Driver aDriver : registeredDrivers) {
+ for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
- if(isDriverAllowed(aDriver, callerCL)) {
+ if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
- println(" trying " + aDriver.getClass().getName());
- Connection con = aDriver.connect(url, info);
+ println(" trying " + aDriver.driver.getClass().getName());
+ Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
- println("getConnection returning " + aDriver.getClass().getName());
+ println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
@@ -607,3 +608,29 @@
private static native ClassLoader getCallerClassLoader();
}
+
+/*
+ * Wrapper class for registered Drivers in order to not expose Driver.equals()
+ * to avoid the capture of the Driver it being compared to as it might not
+ * normally have access.
+ */
+class DriverInfo {
+
+ final Driver driver;
+ DriverInfo(Driver driver) {
+ this.driver = driver;
+ }
+
+ public boolean equals(Object other) {
+ return (other instanceof DriverInfo)
+ && this.driver == ((DriverInfo) other).driver;
+ }
+
+ public int hashCode() {
+ return driver.hashCode();
+ }
+
+ public String toString() {
+ return ("driver[className=" + driver + "]");
+ }
+}
--- a/jdk/src/share/classes/java/util/AbstractQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/AbstractQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util;
--- a/jdk/src/share/classes/java/util/ArrayDeque.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/ArrayDeque.java Tue Apr 12 14:23:03 2011 -0700
@@ -29,7 +29,7 @@
* file:
*
* Written by Josh Bloch of Google Inc. and released to the public domain,
- * as explained at http://creativecommons.org/licenses/publicdomain.
+ * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
*/
package java.util;
--- a/jdk/src/share/classes/java/util/Deque.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/Deque.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea and Josh Bloch with assistance from members of
* JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util;
--- a/jdk/src/share/classes/java/util/EnumMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/EnumMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -106,7 +106,7 @@
/**
* Distinguished non-null value for representing null values.
*/
- private static final Object NULL = new Object();
+ private static final Object NULL = new Integer(0);
private Object maskNull(Object value) {
return (value == null ? NULL : value);
@@ -116,7 +116,7 @@
return (V) (value == NULL ? null : value);
}
- private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
+ private static final Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
/**
* Creates an empty enum map with the specified key type.
@@ -464,6 +464,7 @@
public Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
+
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
@@ -552,70 +553,82 @@
}
}
- /**
- * Since we don't use Entry objects, we use the Iterator itself as entry.
- */
- private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>>
- implements Map.Entry<K,V>
- {
+ private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
+ private Entry lastReturnedEntry = null;
+
public Map.Entry<K,V> next() {
if (!hasNext())
throw new NoSuchElementException();
- lastReturnedIndex = index++;
- return this;
- }
-
- public K getKey() {
- checkLastReturnedIndexForEntryUse();
- return keyUniverse[lastReturnedIndex];
+ lastReturnedEntry = new Entry(index++);
+ return lastReturnedEntry;
}
- public V getValue() {
- checkLastReturnedIndexForEntryUse();
- return unmaskNull(vals[lastReturnedIndex]);
- }
-
- public V setValue(V value) {
- checkLastReturnedIndexForEntryUse();
- V oldValue = unmaskNull(vals[lastReturnedIndex]);
- vals[lastReturnedIndex] = maskNull(value);
- return oldValue;
+ public void remove() {
+ lastReturnedIndex =
+ ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
+ super.remove();
+ lastReturnedEntry.index = lastReturnedIndex;
+ lastReturnedEntry = null;
}
- public boolean equals(Object o) {
- if (lastReturnedIndex < 0)
- return o == this;
+ private class Entry implements Map.Entry<K,V> {
+ private int index;
+
+ private Entry(int index) {
+ this.index = index;
+ }
+
+ public K getKey() {
+ checkIndexForEntryUse();
+ return keyUniverse[index];
+ }
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry e = (Map.Entry)o;
- V ourValue = unmaskNull(vals[lastReturnedIndex]);
- Object hisValue = e.getValue();
- return e.getKey() == keyUniverse[lastReturnedIndex] &&
- (ourValue == hisValue ||
- (ourValue != null && ourValue.equals(hisValue)));
- }
+ public V getValue() {
+ checkIndexForEntryUse();
+ return unmaskNull(vals[index]);
+ }
+
+ public V setValue(V value) {
+ checkIndexForEntryUse();
+ V oldValue = unmaskNull(vals[index]);
+ vals[index] = maskNull(value);
+ return oldValue;
+ }
+
+ public boolean equals(Object o) {
+ if (index < 0)
+ return o == this;
- public int hashCode() {
- if (lastReturnedIndex < 0)
- return super.hashCode();
+ if (!(o instanceof Map.Entry))
+ return false;
- Object value = vals[lastReturnedIndex];
- return keyUniverse[lastReturnedIndex].hashCode()
- ^ (value == NULL ? 0 : value.hashCode());
- }
+ Map.Entry e = (Map.Entry)o;
+ V ourValue = unmaskNull(vals[index]);
+ Object hisValue = e.getValue();
+ return (e.getKey() == keyUniverse[index] &&
+ (ourValue == hisValue ||
+ (ourValue != null && ourValue.equals(hisValue))));
+ }
+
+ public int hashCode() {
+ if (index < 0)
+ return super.hashCode();
- public String toString() {
- if (lastReturnedIndex < 0)
- return super.toString();
+ return entryHashCode(index);
+ }
+
+ public String toString() {
+ if (index < 0)
+ return super.toString();
- return keyUniverse[lastReturnedIndex] + "="
- + unmaskNull(vals[lastReturnedIndex]);
- }
+ return keyUniverse[index] + "="
+ + unmaskNull(vals[index]);
+ }
- private void checkLastReturnedIndexForEntryUse() {
- if (lastReturnedIndex < 0)
- throw new IllegalStateException("Entry was removed");
+ private void checkIndexForEntryUse() {
+ if (index < 0)
+ throw new IllegalStateException("Entry was removed");
+ }
}
}
@@ -631,10 +644,35 @@
* @return <tt>true</tt> if the specified object is equal to this map
*/
public boolean equals(Object o) {
- if (!(o instanceof EnumMap))
- return super.equals(o);
+ if (this == o)
+ return true;
+ if (o instanceof EnumMap)
+ return equals((EnumMap)o);
+ if (!(o instanceof Map))
+ return false;
+
+ Map<K,V> m = (Map<K,V>)o;
+ if (size != m.size())
+ return false;
- EnumMap em = (EnumMap)o;
+ for (int i = 0; i < keyUniverse.length; i++) {
+ if (null != vals[i]) {
+ K key = keyUniverse[i];
+ V value = unmaskNull(vals[i]);
+ if (null == value) {
+ if (!((null == m.get(key)) && m.containsKey(key)))
+ return false;
+ } else {
+ if (!value.equals(m.get(key)))
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private boolean equals(EnumMap em) {
if (em.keyType != keyType)
return size == 0 && em.size == 0;
@@ -650,6 +688,26 @@
}
/**
+ * Returns the hash code value for this map. The hash code of a map is
+ * defined to be the sum of the hash codes of each entry in the map.
+ */
+ public int hashCode() {
+ int h = 0;
+
+ for (int i = 0; i < keyUniverse.length; i++) {
+ if (null != vals[i]) {
+ h += entryHashCode(i);
+ }
+ }
+
+ return h;
+ }
+
+ private int entryHashCode(int index) {
+ return (keyUniverse[index].hashCode() ^ vals[index].hashCode());
+ }
+
+ /**
* Returns a shallow copy of this enum map. (The values themselves
* are not cloned.
*
@@ -705,9 +763,13 @@
s.writeInt(size);
// Write out keys and values (alternating)
- for (Map.Entry<K,V> e : entrySet()) {
- s.writeObject(e.getKey());
- s.writeObject(e.getValue());
+ int entriesToBeWritten = size;
+ for (int i = 0; entriesToBeWritten > 0; i++) {
+ if (null != vals[i]) {
+ s.writeObject(keyUniverse[i]);
+ s.writeObject(unmaskNull(vals[i]));
+ entriesToBeWritten--;
+ }
}
}
--- a/jdk/src/share/classes/java/util/IdentityHashMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -829,71 +829,82 @@
}
}
- /**
- * Since we don't use Entry objects, we use the Iterator
- * itself as an entry.
- */
private class EntryIterator
extends IdentityHashMapIterator<Map.Entry<K,V>>
- implements Map.Entry<K,V>
{
+ private Entry lastReturnedEntry = null;
+
public Map.Entry<K,V> next() {
- nextIndex();
- return this;
+ lastReturnedEntry = new Entry(nextIndex());
+ return lastReturnedEntry;
}
- public K getKey() {
- // Provide a better exception than out of bounds index
- if (lastReturnedIndex < 0)
- throw new IllegalStateException("Entry was removed");
-
- return (K) unmaskNull(traversalTable[lastReturnedIndex]);
- }
-
- public V getValue() {
- // Provide a better exception than out of bounds index
- if (lastReturnedIndex < 0)
- throw new IllegalStateException("Entry was removed");
-
- return (V) traversalTable[lastReturnedIndex+1];
+ public void remove() {
+ lastReturnedIndex =
+ ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
+ super.remove();
+ lastReturnedEntry.index = lastReturnedIndex;
+ lastReturnedEntry = null;
}
- public V setValue(V value) {
- // It would be mean-spirited to proceed here if remove() called
- if (lastReturnedIndex < 0)
- throw new IllegalStateException("Entry was removed");
- V oldValue = (V) traversalTable[lastReturnedIndex+1];
- traversalTable[lastReturnedIndex+1] = value;
- // if shadowing, force into main table
- if (traversalTable != IdentityHashMap.this.table)
- put((K) traversalTable[lastReturnedIndex], value);
- return oldValue;
- }
+ private class Entry implements Map.Entry<K,V> {
+ private int index;
+
+ private Entry(int index) {
+ this.index = index;
+ }
+
+ public K getKey() {
+ checkIndexForEntryUse();
+ return (K) unmaskNull(traversalTable[index]);
+ }
- public boolean equals(Object o) {
- if (lastReturnedIndex < 0)
- return super.equals(o);
+ public V getValue() {
+ checkIndexForEntryUse();
+ return (V) traversalTable[index+1];
+ }
+
+ public V setValue(V value) {
+ checkIndexForEntryUse();
+ V oldValue = (V) traversalTable[index+1];
+ traversalTable[index+1] = value;
+ // if shadowing, force into main table
+ if (traversalTable != IdentityHashMap.this.table)
+ put((K) traversalTable[index], value);
+ return oldValue;
+ }
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry e = (Map.Entry)o;
- return e.getKey() == getKey() &&
- e.getValue() == getValue();
- }
+ public boolean equals(Object o) {
+ if (index < 0)
+ return super.equals(o);
+
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry)o;
+ return (e.getKey() == unmaskNull(traversalTable[index]) &&
+ e.getValue() == traversalTable[index+1]);
+ }
+
+ public int hashCode() {
+ if (lastReturnedIndex < 0)
+ return super.hashCode();
- public int hashCode() {
- if (lastReturnedIndex < 0)
- return super.hashCode();
+ return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
+ System.identityHashCode(traversalTable[index+1]));
+ }
+
+ public String toString() {
+ if (index < 0)
+ return super.toString();
- return System.identityHashCode(getKey()) ^
- System.identityHashCode(getValue());
- }
+ return (unmaskNull(traversalTable[index]) + "="
+ + traversalTable[index+1]);
+ }
- public String toString() {
- if (lastReturnedIndex < 0)
- return super.toString();
-
- return getKey() + "=" + getValue();
+ private void checkIndexForEntryUse() {
+ if (index < 0)
+ throw new IllegalStateException("Entry was removed");
+ }
}
}
--- a/jdk/src/share/classes/java/util/NavigableMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/NavigableMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea and Josh Bloch with assistance from members of JCP
* JSR-166 Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util;
--- a/jdk/src/share/classes/java/util/NavigableSet.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/NavigableSet.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea and Josh Bloch with assistance from members of JCP
* JSR-166 Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util;
--- a/jdk/src/share/classes/java/util/Queue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/Queue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util;
--- a/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/AbstractExecutorService.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingDeque.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BlockingQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/BrokenBarrierException.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/BrokenBarrierException.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Callable.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Callable.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/CancellationException.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CancellationException.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/CompletionService.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CompletionService.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea and Martin Buchholz with assistance from members of
* JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea and Martin Buchholz with assistance from members of
* JCP JSR-166 Expert Group and released to the public domain, as explained
- * at http://creativecommons.org/licenses/publicdomain
+ * at http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CountDownLatch.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/CyclicBarrier.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/CyclicBarrier.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
--- a/jdk/src/share/classes/java/util/concurrent/Delayed.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Delayed.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Exchanger.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Exchanger.java Tue Apr 12 14:23:03 2011 -0700
@@ -31,7 +31,7 @@
* Written by Doug Lea, Bill Scherer, and Michael Scott with
* assistance from members of JCP JSR-166 Expert Group and released to
* the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ExecutionException.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ExecutionException.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Executor.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Executor.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ExecutorCompletionService.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ExecutorCompletionService.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ExecutorService.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ExecutorService.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Executors.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Executors.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
@@ -791,18 +791,19 @@
/**
* Tries to enqueue worker w in wait queue and await change in
- * worker's eventCount. If the pool is quiescent, possibly
- * terminates worker upon exit. Otherwise, before blocking,
- * rescans queues to avoid missed signals. Upon finding work,
- * releases at least one worker (which may be the current
- * worker). Rescans restart upon detected staleness or failure to
- * release due to contention. Note the unusual conventions about
- * Thread.interrupt here and elsewhere: Because interrupts are
- * used solely to alert threads to check termination, which is
- * checked here anyway, we clear status (using Thread.interrupted)
- * before any call to park, so that park does not immediately
- * return due to status being set via some other unrelated call to
- * interrupt in user code.
+ * worker's eventCount. If the pool is quiescent and there is
+ * more than one worker, possibly terminates worker upon exit.
+ * Otherwise, before blocking, rescans queues to avoid missed
+ * signals. Upon finding work, releases at least one worker
+ * (which may be the current worker). Rescans restart upon
+ * detected staleness or failure to release due to
+ * contention. Note the unusual conventions about Thread.interrupt
+ * here and elsewhere: Because interrupts are used solely to alert
+ * threads to check termination, which is checked here anyway, we
+ * clear status (using Thread.interrupted) before any call to
+ * park, so that park does not immediately return due to status
+ * being set via some other unrelated call to interrupt in user
+ * code.
*
* @param w the calling worker
* @param c the ctl value on entry
@@ -823,7 +824,7 @@
else if (w.eventCount != v)
return true; // update next time
}
- if (parallelism + (int)(nc >> AC_SHIFT) == 0 &&
+ if ((int)c != 0 && parallelism + (int)(nc >> AC_SHIFT) == 0 &&
blockedCount == 0 && quiescerCount == 0)
idleAwaitWork(w, nc, c, v); // quiescent
for (boolean rescanned = false;;) {
@@ -893,7 +894,8 @@
w.parked = false;
if (w.eventCount != v)
break;
- else if (System.nanoTime() - startTime < SHRINK_RATE)
+ else if (System.nanoTime() - startTime <
+ SHRINK_RATE - (SHRINK_RATE / 10)) // timing slop
Thread.interrupted(); // spurious wakeup
else if (UNSAFE.compareAndSwapLong(this, ctlOffset,
currentCtl, prevCtl)) {
@@ -1175,7 +1177,7 @@
ws[k] = w;
nextWorkerIndex = k + 1;
int m = g & SMASK;
- g = k >= m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
+ g = k > m? ((m << 1) + 1) & SMASK : g + (SG_UNIT<<1);
}
} finally {
scanGuard = g;
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Future.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Future.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/FutureTask.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/FutureTask.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Phaser.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Phaser.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RecursiveAction.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RecursiveTask.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RecursiveTask.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RejectedExecutionException.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RejectedExecutionException.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RejectedExecutionHandler.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RejectedExecutionHandler.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RunnableFuture.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RunnableFuture.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ScheduledFuture.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledFuture.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/Semaphore.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Semaphore.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/SynchronousQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -31,7 +31,7 @@
* Written by Doug Lea, Bill Scherer, and Michael Scott with
* assistance from members of JCP JSR-166 Expert Group and released to
* the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ThreadFactory.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadFactory.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/TimeUnit.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/TimeUnit.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/TimeoutException.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/TimeoutException.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/TransferQueue.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/TransferQueue.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.atomic;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/package-info.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/package-info.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/Condition.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/Condition.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/Lock.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/Lock.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/ReadWriteLock.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReadWriteLock.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantLock.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantLock.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
package java.util.concurrent.locks;
--- a/jdk/src/share/classes/java/util/concurrent/locks/package-info.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/package-info.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/src/share/classes/java/util/concurrent/package-info.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/package-info.java Tue Apr 12 14:23:03 2011 -0700
@@ -30,7 +30,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/src/share/classes/java/util/jar/JarFile.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java Tue Apr 12 14:23:03 2011 -0700
@@ -37,6 +37,7 @@
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets;
+import sun.security.util.SignatureFileVerifier;
/**
* The <code>JarFile</code> class is used to read the contents of a jar file
@@ -178,7 +179,7 @@
byte[] b = getBytes(manEntry);
man = new Manifest(new ByteArrayInputStream(b));
if (!jvInitialized) {
- jv = new JarVerifier(b);
+ jv = new JarVerifier(b, man);
}
} else {
man = new Manifest(super.getInputStream(manEntry));
@@ -297,10 +298,7 @@
if (names != null) {
for (int i = 0; i < names.length; i++) {
String name = names[i].toUpperCase(Locale.ENGLISH);
- if (name.endsWith(".DSA") ||
- name.endsWith(".RSA") ||
- name.endsWith(".EC") ||
- name.endsWith(".SF")) {
+ if (SignatureFileVerifier.isBlockOrSF(name)) {
// Assume since we found a signature-related file
// that the jar is signed and that we therefore
// need a JarVerifier and Manifest
@@ -329,17 +327,17 @@
if (names != null) {
for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]);
- if (!e.isDirectory()) {
+ if (!e.isDirectory() &&
+ SignatureFileVerifier.isBlock(names[i])) {
if (mev == null) {
mev = new ManifestEntryVerifier
(getManifestFromReference());
}
- byte[] b = getBytes(e);
- if (b != null && b.length > 0) {
- jv.beginEntry(e, mev);
- jv.update(b.length, b, 0, b.length, mev);
- jv.update(-1, null, 0, 0, mev);
- }
+ String key = names[i].substring(
+ 0, names[i].lastIndexOf("."));
+ jv.verifyBlock(names[i],
+ getBytes(e),
+ super.getInputStream(getJarEntry(key + ".SF")));
}
}
}
--- a/jdk/src/share/classes/java/util/jar/JarInputStream.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,7 @@
man.read(new ByteArrayInputStream(bytes));
closeEntry();
if (doVerify) {
- jv = new JarVerifier(bytes);
+ jv = new JarVerifier(bytes, man);
mev = new ManifestEntryVerifier(man);
}
return (JarEntry)super.getNextEntry();
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Tue Apr 12 14:23:03 2011 -0700
@@ -48,35 +48,18 @@
/* a table mapping names to code signers, for jar entries that have
had their actual hashes verified */
- private Hashtable verifiedSigners;
+ private Map verifiedSigners;
/* a table mapping names to code signers, for jar entries that have
passed the .SF/.DSA/.EC -> MANIFEST check */
- private Hashtable sigFileSigners;
-
- /* a hash table to hold .SF bytes */
- private Hashtable sigFileData;
-
- /** "queue" of pending PKCS7 blocks that we couldn't parse
- * until we parsed the .SF file */
- private ArrayList pendingBlocks;
+ private Map sigFileSigners;
/* cache of CodeSigner objects */
private ArrayList signerCache;
- /* Are we parsing a block? */
- private boolean parsingBlockOrSF = false;
-
- /* Are we done parsing META-INF entries? */
- private boolean parsingMeta = true;
-
/* Are there are files to verify? */
private boolean anyToVerify = true;
- /* The output stream to use when keeping track of files we are interested
- in */
- private ByteArrayOutputStream baos;
-
/** The ManifestDigester object */
private volatile ManifestDigester manDig;
@@ -92,20 +75,20 @@
/** collect -DIGEST-MANIFEST values for blacklist */
private List manifestDigests;
- public JarVerifier(byte rawBytes[]) {
+ /** The manifest object */
+ Manifest man = null;
+
+ public JarVerifier(byte rawBytes[], Manifest man) {
+ this.man = man;
manifestRawBytes = rawBytes;
- sigFileSigners = new Hashtable();
- verifiedSigners = new Hashtable();
- sigFileData = new Hashtable(11);
- pendingBlocks = new ArrayList();
- baos = new ByteArrayOutputStream();
+ sigFileSigners = new HashMap();
+ verifiedSigners = new HashMap();
manifestDigests = new ArrayList();
}
/**
- * This method scans to see which entry we're parsing and
- * keeps various state information depending on what type of
- * file is being parsed.
+ * This method scans to see which entry we're parsing and keeps
+ * various state information depending on the file being parsed.
*/
public void beginEntry(JarEntry je, ManifestEntryVerifier mev)
throws IOException
@@ -129,30 +112,6 @@
* b. digest mismatch between the actual jar entry and the manifest
*/
- if (parsingMeta) {
- String uname = name.toUpperCase(Locale.ENGLISH);
- if ((uname.startsWith("META-INF/") ||
- uname.startsWith("/META-INF/"))) {
-
- if (je.isDirectory()) {
- mev.setEntry(null, je);
- return;
- }
-
- if (SignatureFileVerifier.isBlockOrSF(uname)) {
- /* We parse only DSA, RSA or EC PKCS7 blocks. */
- parsingBlockOrSF = true;
- baos.reset();
- mev.setEntry(null, je);
- }
- return;
- }
- }
-
- if (parsingMeta) {
- doneWithMeta();
- }
-
if (je.isDirectory()) {
mev.setEntry(null, je);
return;
@@ -188,11 +147,7 @@
throws IOException
{
if (b != -1) {
- if (parsingBlockOrSF) {
- baos.write(b);
- } else {
- mev.update((byte)b);
- }
+ mev.update((byte)b);
} else {
processEntry(mev);
}
@@ -207,11 +162,7 @@
throws IOException
{
if (n != -1) {
- if (parsingBlockOrSF) {
- baos.write(b, off, n);
- } else {
- mev.update(b, off, n);
- }
+ mev.update(b, off, n);
} else {
processEntry(mev);
}
@@ -223,101 +174,10 @@
private void processEntry(ManifestEntryVerifier mev)
throws IOException
{
- if (!parsingBlockOrSF) {
- JarEntry je = mev.getEntry();
- if ((je != null) && (je.signers == null)) {
- je.signers = mev.verify(verifiedSigners, sigFileSigners);
- je.certs = mapSignersToCertArray(je.signers);
- }
- } else {
-
- try {
- parsingBlockOrSF = false;
-
- if (debug != null) {
- debug.println("processEntry: processing block");
- }
-
- String uname = mev.getEntry().getName()
- .toUpperCase(Locale.ENGLISH);
-
- if (uname.endsWith(".SF")) {
- String key = uname.substring(0, uname.length()-3);
- byte bytes[] = baos.toByteArray();
- // add to sigFileData in case future blocks need it
- sigFileData.put(key, bytes);
- // check pending blocks, we can now process
- // anyone waiting for this .SF file
- Iterator it = pendingBlocks.iterator();
- while (it.hasNext()) {
- SignatureFileVerifier sfv =
- (SignatureFileVerifier) it.next();
- if (sfv.needSignatureFile(key)) {
- if (debug != null) {
- debug.println(
- "processEntry: processing pending block");
- }
-
- sfv.setSignatureFile(bytes);
- sfv.process(sigFileSigners, manifestDigests);
- }
- }
- return;
- }
-
- // now we are parsing a signature block file
-
- String key = uname.substring(0, uname.lastIndexOf("."));
-
- if (signerCache == null)
- signerCache = new ArrayList();
-
- if (manDig == null) {
- synchronized(manifestRawBytes) {
- if (manDig == null) {
- manDig = new ManifestDigester(manifestRawBytes);
- manifestRawBytes = null;
- }
- }
- }
-
- SignatureFileVerifier sfv =
- new SignatureFileVerifier(signerCache,
- manDig, uname, baos.toByteArray());
-
- if (sfv.needSignatureFileBytes()) {
- // see if we have already parsed an external .SF file
- byte[] bytes = (byte[]) sigFileData.get(key);
-
- if (bytes == null) {
- // put this block on queue for later processing
- // since we don't have the .SF bytes yet
- // (uname, block);
- if (debug != null) {
- debug.println("adding pending block");
- }
- pendingBlocks.add(sfv);
- return;
- } else {
- sfv.setSignatureFile(bytes);
- }
- }
- sfv.process(sigFileSigners, manifestDigests);
-
- } catch (IOException ioe) {
- // e.g. sun.security.pkcs.ParsingException
- if (debug != null) debug.println("processEntry caught: "+ioe);
- // ignore and treat as unsigned
- } catch (SignatureException se) {
- if (debug != null) debug.println("processEntry caught: "+se);
- // ignore and treat as unsigned
- } catch (NoSuchAlgorithmException nsae) {
- if (debug != null) debug.println("processEntry caught: "+nsae);
- // ignore and treat as unsigned
- } catch (CertificateException ce) {
- if (debug != null) debug.println("processEntry caught: "+ce);
- // ignore and treat as unsigned
- }
+ JarEntry je = mev.getEntry();
+ if ((je != null) && (je.signers == null)) {
+ je.signers = mev.verify(verifiedSigners, sigFileSigners);
+ je.certs = mapSignersToCertArray(je.signers);
}
}
@@ -354,15 +214,15 @@
* Force a read of the entry data to generate the
* verification hash.
*/
- try {
- InputStream s = jar.getInputStream(entry);
+ try (InputStream s = jar.getInputStream(entry)) {
byte[] buffer = new byte[1024];
int n = buffer.length;
while (n != -1) {
n = s.read(buffer, 0, buffer.length);
}
- s.close();
} catch (IOException e) {
+ // Ignore. When an exception is thrown, code signer
+ // will not be assigned.
}
}
return getCodeSigners(name);
@@ -408,11 +268,7 @@
*/
void doneWithMeta()
{
- parsingMeta = false;
anyToVerify = !sigFileSigners.isEmpty();
- baos = null;
- sigFileData = null;
- pendingBlocks = null;
signerCache = null;
manDig = null;
// MANIFEST.MF is always treated as signed and verified,
@@ -423,6 +279,41 @@
}
}
+ /**
+ * Verifies a PKCS7 SignedData block
+ * @param key name of block
+ * @param block the pkcs7 file
+ * @param ins the clear data
+ */
+ void verifyBlock(String key, byte[] block, InputStream ins) {
+ try {
+ if (signerCache == null)
+ signerCache = new ArrayList();
+
+ if (manDig == null) {
+ synchronized(manifestRawBytes) {
+ if (manDig == null) {
+ manDig = new ManifestDigester(manifestRawBytes);
+ manifestRawBytes = null;
+ }
+ }
+ }
+ SignatureFileVerifier sfv =
+ new SignatureFileVerifier(signerCache, man,
+ manDig, key, block);
+
+ if (sfv.needSignatureFile()) {
+ // see if we have already parsed an external .SF file
+ sfv.setSignatureFile(ins);
+ }
+ sfv.process(sigFileSigners, manifestDigests);
+ } catch (Exception e) {
+ if (debug != null) {
+ e.printStackTrace();
+ }
+ }
+ }
+
static class VerifierStream extends java.io.InputStream {
private InputStream is;
@@ -553,10 +444,7 @@
* but this handles a CodeSource of any type, just in case.
*/
CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
- List sourceList = new ArrayList();
- for (int i = 0; i < sources.length; i++) {
- sourceList.add(sources[i]);
- }
+ List sourceList = Arrays.asList(sources);
int j = sourceList.indexOf(cs);
if (j != -1) {
CodeSigner[] match;
--- a/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/java/util/zip/DeflaterOutputStream.java Tue Apr 12 14:23:03 2011 -0700
@@ -206,14 +206,9 @@
return;
}
if (!def.finished()) {
- // Deflate no more than stride bytes at a time. This avoids
- // excess copying in deflateBytes (see Deflater.c)
- int stride = buf.length;
- for (int i = 0; i < len; i+= stride) {
- def.setInput(b, off + i, Math.min(stride, len - i));
- while (!def.needsInput()) {
- deflate();
- }
+ def.setInput(b, off, len);
+ while (!def.needsInput()) {
+ deflate();
}
}
}
--- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java Tue Apr 12 14:23:03 2011 -0700
@@ -710,8 +710,8 @@
*
* @param x the x value of the region to be painted
* @param y the y value of the region to be painted
- * @param w the width of the region to be painted
- * @param h the height of the region to be painted
+ * @param width the width of the region to be painted
+ * @param height the height of the region to be painted
*
* @see JComponent#paintImmediately(int, int, int, int)
*/
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -388,9 +388,8 @@
// we must instead use a nonempty buffer, otherwise the call
// will not block waiting for a datagram on some platforms.
int newSize = Math.max(rem, 1);
- ByteBuffer bb = null;
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(newSize);
try {
- bb = Util.getTemporaryDirectBuffer(newSize);
int n = receiveIntoNativeBuffer(fd, bb, newSize, 0);
bb.flip();
if (n > 0 && rem > 0)
@@ -482,9 +481,8 @@
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- ByteBuffer bb = null;
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
try {
- bb = Util.getTemporaryDirectBuffer(rem);
bb.put(src);
bb.flip();
// Do not update src until we see how many bytes were written
@@ -766,10 +764,10 @@
// check multicast address is compatible with this socket
if (group instanceof Inet4Address) {
if (family == StandardProtocolFamily.INET6 && !Net.canIPv6SocketJoinIPv4Group())
- throw new IllegalArgumentException("Group is not IPv4 multicast address");
+ throw new IllegalArgumentException("IPv6 socket cannot join IPv4 multicast group");
} else if (group instanceof Inet6Address) {
if (family != StandardProtocolFamily.INET6)
- throw new IllegalArgumentException("Group is not IPv6 multicast address");
+ throw new IllegalArgumentException("Only IPv6 sockets can join IPv6 multicast group");
} else {
throw new IllegalArgumentException("Address type not supported");
}
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java Tue Apr 12 14:23:03 2011 -0700
@@ -50,9 +50,8 @@
int lim = src.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
- ByteBuffer bb = null;
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
try {
- bb = Util.getTemporaryDirectBuffer(rem);
bb.put(src);
bb.flip();
// Do not update src until we see how many bytes were written
@@ -187,9 +186,8 @@
return readIntoNativeBuffer(fd, dst, position, nd, lock);
// Substitute a native buffer
- ByteBuffer bb = null;
+ ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
try {
- bb = Util.getTemporaryDirectBuffer(dst.remaining());
int n = readIntoNativeBuffer(fd, bb, position, nd, lock);
bb.flip();
if (n > 0)
--- a/jdk/src/share/classes/sun/nio/fs/Util.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/fs/Util.java Tue Apr 12 14:23:03 2011 -0700
@@ -26,6 +26,7 @@
package sun.nio.fs;
import java.util.*;
+import java.nio.file.*;
/**
* Utility methods
@@ -80,4 +81,21 @@
}
return set;
}
+
+ /**
+ * Returns {@code true} if symbolic links should be followed
+ */
+ static boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption option: options) {
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ } else if (option == null) {
+ throw new NullPointerException();
+ } else {
+ throw new AssertionError("Should not get here");
+ }
+ }
+ return followLinks;
+ }
}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,8 +127,8 @@
//System.out.println("Sub-Session Key Missing in Authenticator.\n");
}
- OverloadedChecksum gssChecksum =
- new OverloadedChecksum(context, apReq.getChecksum(), sessionKey);
+ OverloadedChecksum gssChecksum = new OverloadedChecksum(
+ context, apReq.getChecksum(), sessionKey, subKey);
gssChecksum.setContextFlags(context);
Credentials delegCred = gssChecksum.getDelegatedCreds();
if (delegCred != null) {
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -210,8 +210,8 @@
// be passed in if this checksum type denotes a
// raw_checksum. In that case, make Checksum class krb5
// internal.
- public OverloadedChecksum(Krb5Context context,
- Checksum checksum, EncryptionKey key)
+ public OverloadedChecksum(Krb5Context context, Checksum checksum,
+ EncryptionKey key, EncryptionKey subKey)
throws GSSException, KrbException, IOException {
int pos = 0;
@@ -283,9 +283,17 @@
new KrbCred(credBytes, EncryptionKey.NULL_KEY).
getDelegatedCreds()[0];
} else {
- delegCreds =
- new KrbCred(credBytes, key).
- getDelegatedCreds()[0];
+ KrbCred cred;
+ try {
+ cred = new KrbCred(credBytes, key);
+ } catch (KrbException e) {
+ if (subKey != null) {
+ cred = new KrbCred(credBytes, subKey);
+ } else {
+ throw e;
+ }
+ }
+ delegCreds = cred.getDelegatedCreds()[0];
}
}
}
--- a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
import java.net.InetAddress;
import sun.security.util.*;
import java.io.IOException;
+import java.util.Arrays;
/**
* This class encapsulates a KRB-AP-REQ that a client sends to a
@@ -54,9 +55,6 @@
private static CacheTable table = new CacheTable();
private static boolean DEBUG = Krb5.DEBUG;
- // default is address-less tickets
- private boolean KDC_EMPTY_ADDRESSES_ALLOWED = true;
-
/**
* Contructs a AP-REQ message to send to the peer.
* @param tgsCred the <code>Credentials</code> to be used to construct the
@@ -312,23 +310,19 @@
table.put(client, time, currTime.getTime());
}
- // check to use addresses in tickets
- if (Config.getInstance().useAddresses()) {
- KDC_EMPTY_ADDRESSES_ALLOWED = false;
- }
-
- // sender host address
- HostAddress sender = null;
if (initiator != null) {
- sender = new HostAddress(initiator);
- }
-
- if (sender != null || !KDC_EMPTY_ADDRESSES_ALLOWED) {
- if (enc_ticketPart.caddr != null) {
- if (sender == null)
- throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
- if (!enc_ticketPart.caddr.inList(sender))
- throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
+ // sender host address
+ HostAddress sender = new HostAddress(initiator);
+ if (enc_ticketPart.caddr != null
+ && !enc_ticketPart.caddr.inList(sender)) {
+ if (DEBUG) {
+ System.out.println(">>> KrbApReq: initiator is "
+ + sender.getInetAddress()
+ + ", but caddr is "
+ + Arrays.toString(
+ enc_ticketPart.caddr.getInetAddresses()));
+ }
+ throw new KrbApErrException(Krb5.KRB_AP_ERR_BADADDR);
}
}
--- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* 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,6 +38,7 @@
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateIssuerName;
+import sun.security.x509.KeyUsageExtension;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
import sun.security.x509.X509CRLImpl;
@@ -492,7 +493,7 @@
// CRLs (optional)
if (crls != null && crls.length != 0) {
// cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
- Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
+ Set<X509CRLImpl> implCRLs = new HashSet<>(crls.length);
for (X509CRL crl: crls) {
if (crl instanceof X509CRLImpl)
implCRLs.add((X509CRLImpl) crl);
@@ -530,6 +531,168 @@
}
/**
+ * Verifying signed data using an external chunked data source.
+ */
+ public static class PKCS7Verifier {
+
+ private final SignerInfo si; // Signer to verify
+ private final MessageDigest md; // MessageDigest object for chunks
+ private final Signature sig; // Signature object for chunks
+
+ private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) {
+ this.si = si;
+ this.md = md;
+ this.sig = sig;
+ }
+
+ public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws
+ SignatureException, NoSuchAlgorithmException {
+
+ try {
+ MessageDigest md = null;
+ Signature sig;
+
+ ContentInfo content = block.getContentInfo();
+ String digestAlgname = si.getDigestAlgorithmId().getName();
+
+ // if there are authenticate attributes, feed data chunks to
+ // the message digest. In this case, pv.md is not null
+ if (si.authenticatedAttributes != null) {
+ // first, check content type
+ ObjectIdentifier contentType = (ObjectIdentifier)
+ si.authenticatedAttributes.getAttributeValue(
+ PKCS9Attribute.CONTENT_TYPE_OID);
+ if (contentType == null ||
+ !contentType.equals(content.contentType))
+ return null; // contentType does not match, bad SignerInfo
+
+ // now, check message digest
+ byte[] messageDigest = (byte[])
+ si.authenticatedAttributes.getAttributeValue(
+ PKCS9Attribute.MESSAGE_DIGEST_OID);
+
+ if (messageDigest == null) // fail if there is no message digest
+ return null;
+
+ md = MessageDigest.getInstance(digestAlgname);
+ }
+
+ // put together digest algorithm and encryption algorithm
+ // to form signing algorithm
+ String encryptionAlgname =
+ si.getDigestEncryptionAlgorithmId().getName();
+
+ // Workaround: sometimes the encryptionAlgname is actually
+ // a signature name
+ String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
+ if (tmp != null) encryptionAlgname = tmp;
+ String algname = AlgorithmId.makeSigAlg(
+ digestAlgname, encryptionAlgname);
+
+ sig = Signature.getInstance(algname);
+ X509Certificate cert = si.getCertificate(block);
+
+ if (cert == null) {
+ return null;
+ }
+ if (cert.hasUnsupportedCriticalExtension()) {
+ throw new SignatureException("Certificate has unsupported "
+ + "critical extension(s)");
+ }
+
+ // Make sure that if the usage of the key in the certificate is
+ // restricted, it can be used for digital signatures.
+ // XXX We may want to check for additional extensions in the
+ // future.
+ boolean[] keyUsageBits = cert.getKeyUsage();
+ if (keyUsageBits != null) {
+ KeyUsageExtension keyUsage;
+ try {
+ // We don't care whether or not this extension was marked
+ // critical in the certificate.
+ // We're interested only in its value (i.e., the bits set)
+ // and treat the extension as critical.
+ keyUsage = new KeyUsageExtension(keyUsageBits);
+ } catch (IOException ioe) {
+ throw new SignatureException("Failed to parse keyUsage "
+ + "extension");
+ }
+
+ boolean digSigAllowed = ((Boolean)keyUsage.get(
+ KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
+
+ boolean nonRepuAllowed = ((Boolean)keyUsage.get(
+ KeyUsageExtension.NON_REPUDIATION)).booleanValue();
+
+ if (!digSigAllowed && !nonRepuAllowed) {
+ throw new SignatureException("Key usage restricted: "
+ + "cannot be used for "
+ + "digital signatures");
+ }
+ }
+
+ PublicKey key = cert.getPublicKey();
+ sig.initVerify(key);
+ return new PKCS7Verifier(si, md, sig);
+ } catch (IOException e) {
+ throw new SignatureException("IO error verifying signature:\n" +
+ e.getMessage());
+
+ } catch (InvalidKeyException e) {
+ throw new SignatureException("InvalidKey: " + e.getMessage());
+
+ }
+ }
+
+ public void update(byte[] data, int off, int end)
+ throws SignatureException {
+ if (md != null) {
+ md.update(data, off, end-off);
+ } else {
+ sig.update(data, off, end-off);
+ }
+ }
+
+ public SignerInfo verify() throws SignatureException {
+ try {
+ // if there are authenticate attributes, get the message
+ // digest and compare it with the digest of data
+ if (md != null) {
+ // now, check message digest
+ byte[] messageDigest = (byte[])
+ si.authenticatedAttributes.getAttributeValue(
+ PKCS9Attribute.MESSAGE_DIGEST_OID);
+
+ byte[] computedMessageDigest = md.digest();
+
+ if (!MessageDigest.isEqual(
+ messageDigest, computedMessageDigest)) {
+ return null;
+ }
+
+ // message digest attribute matched
+ // digest of original data
+
+ // the data actually signed is the DER encoding of
+ // the authenticated attributes (tagged with
+ // the "SET OF" tag, not 0xA0).
+ byte[] dataSigned = si.authenticatedAttributes.getDerEncoding();
+ sig.update(dataSigned);
+ }
+
+ if (sig.verify(si.getEncryptedDigest())) {
+ return si;
+ }
+
+ } catch (IOException e) {
+ throw new SignatureException("IO error verifying signature:\n" +
+ e.getMessage());
+ }
+ return null;
+ }
+ }
+
+ /**
* This verifies a given SignerInfo.
*
* @param info the signer information.
@@ -554,19 +717,16 @@
public SignerInfo[] verify(byte[] bytes)
throws NoSuchAlgorithmException, SignatureException {
- Vector<SignerInfo> intResult = new Vector<SignerInfo>();
+ List<SignerInfo> intResult = new ArrayList<>();
for (int i = 0; i < signerInfos.length; i++) {
SignerInfo signerInfo = verify(signerInfos[i], bytes);
if (signerInfo != null) {
- intResult.addElement(signerInfo);
+ intResult.add(signerInfo);
}
}
- if (intResult.size() != 0) {
-
- SignerInfo[] result = new SignerInfo[intResult.size()];
- intResult.copyInto(result);
- return result;
+ if (!intResult.isEmpty()) {
+ return intResult.toArray(new SignerInfo[intResult.size()]);
}
return null;
}
--- a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -230,7 +230,7 @@
if (userCert == null)
return null;
- ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
+ ArrayList<X509Certificate> certList = new ArrayList<>();
certList.add(userCert);
X509Certificate[] pkcsCerts = block.getCertificates();
@@ -276,132 +276,20 @@
/* Returns null if verify fails, this signerInfo if
verify succeeds. */
SignerInfo verify(PKCS7 block, byte[] data)
- throws NoSuchAlgorithmException, SignatureException {
-
- try {
-
- ContentInfo content = block.getContentInfo();
- if (data == null) {
- data = content.getContentBytes();
- }
-
- String digestAlgname = getDigestAlgorithmId().getName();
-
- byte[] dataSigned;
-
- // if there are authenticate attributes, get the message
- // digest and compare it with the digest of data
- if (authenticatedAttributes == null) {
- dataSigned = data;
- } else {
-
- // first, check content type
- ObjectIdentifier contentType = (ObjectIdentifier)
- authenticatedAttributes.getAttributeValue(
- PKCS9Attribute.CONTENT_TYPE_OID);
- if (contentType == null ||
- !contentType.equals(content.contentType))
- return null; // contentType does not match, bad SignerInfo
-
- // now, check message digest
- byte[] messageDigest = (byte[])
- authenticatedAttributes.getAttributeValue(
- PKCS9Attribute.MESSAGE_DIGEST_OID);
-
- if (messageDigest == null) // fail if there is no message digest
- return null;
-
- MessageDigest md = MessageDigest.getInstance(digestAlgname);
- byte[] computedMessageDigest = md.digest(data);
-
- if (messageDigest.length != computedMessageDigest.length)
- return null;
- for (int i = 0; i < messageDigest.length; i++) {
- if (messageDigest[i] != computedMessageDigest[i])
- return null;
- }
-
- // message digest attribute matched
- // digest of original data
-
- // the data actually signed is the DER encoding of
- // the authenticated attributes (tagged with
- // the "SET OF" tag, not 0xA0).
- dataSigned = authenticatedAttributes.getDerEncoding();
- }
-
- // put together digest algorithm and encryption algorithm
- // to form signing algorithm
- String encryptionAlgname =
- getDigestEncryptionAlgorithmId().getName();
+ throws NoSuchAlgorithmException, SignatureException {
- // Workaround: sometimes the encryptionAlgname is actually
- // a signature name
- String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
- if (tmp != null) encryptionAlgname = tmp;
- String algname = AlgorithmId.makeSigAlg(
- digestAlgname, encryptionAlgname);
-
- Signature sig = Signature.getInstance(algname);
- X509Certificate cert = getCertificate(block);
-
- if (cert == null) {
- return null;
- }
- if (cert.hasUnsupportedCriticalExtension()) {
- throw new SignatureException("Certificate has unsupported "
- + "critical extension(s)");
+ PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this);
+ if (p7v == null) return null;
+ if (data == null) {
+ try {
+ data = block.getContentInfo().getContentBytes();
+ } catch (IOException e) {
+ throw new SignatureException("IO error verifying signature:\n" +
+ e.getMessage());
}
-
- // Make sure that if the usage of the key in the certificate is
- // restricted, it can be used for digital signatures.
- // XXX We may want to check for additional extensions in the
- // future.
- boolean[] keyUsageBits = cert.getKeyUsage();
- if (keyUsageBits != null) {
- KeyUsageExtension keyUsage;
- try {
- // We don't care whether or not this extension was marked
- // critical in the certificate.
- // We're interested only in its value (i.e., the bits set)
- // and treat the extension as critical.
- keyUsage = new KeyUsageExtension(keyUsageBits);
- } catch (IOException ioe) {
- throw new SignatureException("Failed to parse keyUsage "
- + "extension");
- }
-
- boolean digSigAllowed = ((Boolean)keyUsage.get(
- KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
-
- boolean nonRepuAllowed = ((Boolean)keyUsage.get(
- KeyUsageExtension.NON_REPUDIATION)).booleanValue();
-
- if (!digSigAllowed && !nonRepuAllowed) {
- throw new SignatureException("Key usage restricted: "
- + "cannot be used for "
- + "digital signatures");
- }
- }
-
- PublicKey key = cert.getPublicKey();
- sig.initVerify(key);
-
- sig.update(dataSigned);
-
- if (sig.verify(encryptedDigest)) {
- return this;
- }
-
- } catch (IOException e) {
- throw new SignatureException("IO error verifying signature:\n" +
- e.getMessage());
-
- } catch (InvalidKeyException e) {
- throw new SignatureException("InvalidKey: " + e.getMessage());
-
}
- return null;
+ p7v.update(data, 0, data.length);
+ return p7v.verify();
}
/* Verify the content of the pkcs7 block. */
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuiteList.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuiteList.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,10 +40,6 @@
*/
final class CipherSuiteList {
- // lists of supported and default enabled ciphersuites
- // created on demand
- private static CipherSuiteList supportedSuites, defaultSuites;
-
private final Collection<CipherSuite> cipherSuites;
private String[] suiteNames;
@@ -206,57 +202,8 @@
*/
static synchronized void clearAvailableCache() {
if (CipherSuite.DYNAMIC_AVAILABILITY) {
- supportedSuites = null;
- defaultSuites = null;
CipherSuite.BulkCipher.clearAvailableCache();
JsseJce.clearEcAvailable();
}
}
-
- /**
- * Return the list of all available CipherSuites with a priority of
- * minPriority or above.
- * Should be called with the Class lock held.
- */
- private static CipherSuiteList buildAvailableCache(int minPriority) {
- // SortedSet automatically arranges ciphersuites in default
- // preference order
- Set<CipherSuite> cipherSuites = new TreeSet<>();
- Collection<CipherSuite> allowedCipherSuites =
- CipherSuite.allowedCipherSuites();
- for (CipherSuite c : allowedCipherSuites) {
- if ((c.allowed == false) || (c.priority < minPriority)) {
- continue;
- }
-
- if (c.isAvailable()) {
- cipherSuites.add(c);
- }
- }
-
- return new CipherSuiteList(cipherSuites);
- }
-
- /**
- * Return supported CipherSuites in preference order.
- */
- static synchronized CipherSuiteList getSupported() {
- if (supportedSuites == null) {
- supportedSuites =
- buildAvailableCache(CipherSuite.SUPPORTED_SUITES_PRIORITY);
- }
- return supportedSuites;
- }
-
- /**
- * Return default enabled CipherSuites in preference order.
- */
- static synchronized CipherSuiteList getDefault() {
- if (defaultSuites == null) {
- defaultSuites =
- buildAvailableCache(CipherSuite.DEFAULT_SUITES_PRIORITY);
- }
- return defaultSuites;
- }
-
}
--- a/jdk/src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.ssl;
-
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-
-import javax.net.ssl.*;
-
-/**
- * "Default" SSLContext as returned by SSLContext.getDefault(). It comes
- * initialized with default KeyManagers and TrustManagers created using
- * various system properties.
- *
- * @since 1.6
- */
-public final class DefaultSSLContextImpl extends SSLContextImpl {
-
- private static final String NONE = "NONE";
- private static final String P11KEYSTORE = "PKCS11";
- private static final Debug debug = Debug.getInstance("ssl");
-
- private static volatile SSLContextImpl defaultImpl;
-
- private static TrustManager[] defaultTrustManagers;
-
- private static KeyManager[] defaultKeyManagers;
-
- public DefaultSSLContextImpl() throws Exception {
- super(defaultImpl);
- try {
- super.engineInit(getDefaultKeyManager(), getDefaultTrustManager(), null);
- } catch (Exception e) {
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("default context init failed: " + e);
- }
- throw e;
- }
- if (defaultImpl == null) {
- defaultImpl = this;
- }
- }
-
- protected void engineInit(KeyManager[] km, TrustManager[] tm,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException
- ("Default SSLContext is initialized automatically");
- }
-
- static synchronized SSLContextImpl getDefaultImpl() throws Exception {
- if (defaultImpl == null) {
- new DefaultSSLContextImpl();
- }
- return defaultImpl;
- }
-
- private static synchronized TrustManager[] getDefaultTrustManager() throws Exception {
- if (defaultTrustManagers != null) {
- return defaultTrustManagers;
- }
-
- KeyStore ks = TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
-
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(ks);
- defaultTrustManagers = tmf.getTrustManagers();
- return defaultTrustManagers;
- }
-
- private static synchronized KeyManager[] getDefaultKeyManager() throws Exception {
- if (defaultKeyManagers != null) {
- return defaultKeyManagers;
- }
-
- final Map<String,String> props = new HashMap<>();
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Object>() {
- public Object run() throws Exception {
- props.put("keyStore", System.getProperty(
- "javax.net.ssl.keyStore", ""));
- props.put("keyStoreType", System.getProperty(
- "javax.net.ssl.keyStoreType",
- KeyStore.getDefaultType()));
- props.put("keyStoreProvider", System.getProperty(
- "javax.net.ssl.keyStoreProvider", ""));
- props.put("keyStorePasswd", System.getProperty(
- "javax.net.ssl.keyStorePassword", ""));
- return null;
- }
- });
-
- final String defaultKeyStore = props.get("keyStore");
- String defaultKeyStoreType = props.get("keyStoreType");
- String defaultKeyStoreProvider = props.get("keyStoreProvider");
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("keyStore is : " + defaultKeyStore);
- System.out.println("keyStore type is : " +
- defaultKeyStoreType);
- System.out.println("keyStore provider is : " +
- defaultKeyStoreProvider);
- }
-
- if (P11KEYSTORE.equals(defaultKeyStoreType) &&
- !NONE.equals(defaultKeyStore)) {
- throw new IllegalArgumentException("if keyStoreType is "
- + P11KEYSTORE + ", then keyStore must be " + NONE);
- }
-
- FileInputStream fs = null;
- if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
- fs = AccessController.doPrivileged(
- new PrivilegedExceptionAction<FileInputStream>() {
- public FileInputStream run() throws Exception {
- return new FileInputStream(defaultKeyStore);
- }
- });
- }
-
- String defaultKeyStorePassword = props.get("keyStorePasswd");
- char[] passwd = null;
- if (defaultKeyStorePassword.length() != 0) {
- passwd = defaultKeyStorePassword.toCharArray();
- }
-
- /**
- * Try to initialize key store.
- */
- KeyStore ks = null;
- if ((defaultKeyStoreType.length()) != 0) {
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("init keystore");
- }
- if (defaultKeyStoreProvider.length() == 0) {
- ks = KeyStore.getInstance(defaultKeyStoreType);
- } else {
- ks = KeyStore.getInstance(defaultKeyStoreType,
- defaultKeyStoreProvider);
- }
-
- // if defaultKeyStore is NONE, fs will be null
- ks.load(fs, passwd);
- }
- if (fs != null) {
- fs.close();
- fs = null;
- }
-
- /*
- * Try to initialize key manager.
- */
- if (debug != null && Debug.isOn("defaultctx")) {
- System.out.println("init keymanager of type " +
- KeyManagerFactory.getDefaultAlgorithm());
- }
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(
- KeyManagerFactory.getDefaultAlgorithm());
-
- if (P11KEYSTORE.equals(defaultKeyStoreType)) {
- kmf.init(ks, null); // do not pass key passwd if using token
- } else {
- kmf.init(ks, passwd);
- }
-
- defaultKeyManagers = kmf.getKeyManagers();
- return defaultKeyManagers;
- }
-}
--- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -247,9 +247,9 @@
// the SunJSSE implementation does the actual crypto using
// a NONEwithRSA signature obtained from the cryptoProvider.
if (cryptoProvider.getService("Signature", algorithm) == null) {
- // Calling Signature.getInstance() and catching the exception
- // would be cleaner, but exceptions are a little expensive.
- // So we check directly via getService().
+ // Calling Signature.getInstance() and catching the
+ // exception would be cleaner, but exceptions are a little
+ // expensive. So we check directly via getService().
try {
return Signature.getInstance(algorithm, "SunJSSE");
} catch (NoSuchProviderException e) {
--- a/jdk/src/share/classes/sun/security/ssl/ProtocolList.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ProtocolList.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* 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,10 +37,6 @@
*/
final class ProtocolList {
- private static final ProtocolList SUPPORTED;
- private static final ProtocolList CLIENT_DEFAULT;
- private static final ProtocolList SERVER_DEFAULT;
-
// the sorted protocol version list
private final ArrayList<ProtocolVersion> protocols;
@@ -154,66 +150,4 @@
public String toString() {
return protocols.toString();
}
-
- /**
- * Return the list of default enabled protocols.
- */
- static ProtocolList getDefault(boolean isServer) {
- return isServer ? SERVER_DEFAULT : CLIENT_DEFAULT;
- }
-
- /**
- * Return whether a protocol list is the original default enabled
- * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
- */
- static boolean isDefaultProtocolList(ProtocolList protocols) {
- return protocols == CLIENT_DEFAULT || protocols == SERVER_DEFAULT;
- }
-
- /**
- * Return the list of supported protocols.
- */
- static ProtocolList getSupported() {
- return SUPPORTED;
- }
-
- static {
- if (SunJSSE.isFIPS()) {
- SUPPORTED = new ProtocolList(new String[] {
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
-
- SERVER_DEFAULT = SUPPORTED;
- CLIENT_DEFAULT = new ProtocolList(new String[] {
- ProtocolVersion.TLS10.name
- });
- } else {
- SUPPORTED = new ProtocolList(new String[] {
- ProtocolVersion.SSL20Hello.name,
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
-
- SERVER_DEFAULT = SUPPORTED;
-
- /*
- * RFC 5246 says that sending SSLv2 backward-compatible
- * hello SHOULD NOT be done any longer.
- *
- * We are not enabling TLS 1.1/1.2 by default yet on clients
- * out of concern for interop with existing
- * SSLv3/TLS1.0-only servers. When these versions of TLS
- * gain more traction, we'll enable them.
- */
- CLIENT_DEFAULT = new ProtocolList(new String[] {
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name
- });
- }
- }
-
}
--- a/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import java.net.Socket;
+import java.io.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
@@ -36,7 +37,7 @@
import sun.security.provider.certpath.AlgorithmChecker;
-public class SSLContextImpl extends SSLContextSpi {
+public abstract class SSLContextImpl extends SSLContextSpi {
private static final Debug debug = Debug.getInstance("ssl");
@@ -50,20 +51,24 @@
private X509TrustManager trustManager;
private SecureRandom secureRandom;
- public SSLContextImpl() {
- this(null);
- }
+ // The default algrithm constraints
+ private AlgorithmConstraints defaultAlgorithmConstraints =
+ new SSLAlgorithmConstraints(null);
+
+ // supported and default protocols
+ private ProtocolList defaultServerProtocolList;
+ private ProtocolList defaultClientProtocolList;
+ private ProtocolList supportedProtocolList;
- SSLContextImpl(SSLContextImpl other) {
- if (other == null) {
- ephemeralKeyManager = new EphemeralKeyManager();
- clientCache = new SSLSessionContextImpl();
- serverCache = new SSLSessionContextImpl();
- } else {
- ephemeralKeyManager = other.ephemeralKeyManager;
- clientCache = other.clientCache;
- serverCache = other.serverCache;
- }
+ // supported and default cipher suites
+ private CipherSuiteList defaultServerCipherSuiteList;
+ private CipherSuiteList defaultClientCipherSuiteList;
+ private CipherSuiteList supportedCipherSuiteList;
+
+ SSLContextImpl() {
+ ephemeralKeyManager = new EphemeralKeyManager();
+ clientCache = new SSLSessionContextImpl();
+ serverCache = new SSLSessionContextImpl();
}
protected void engineInit(KeyManager[] km, TrustManager[] tm,
@@ -177,7 +182,7 @@
throw new IllegalStateException(
"SSLContextImpl is not initialized");
}
- return new SSLSocketFactoryImpl(this);
+ return new SSLSocketFactoryImpl(this);
}
protected SSLServerSocketFactory engineGetServerSocketFactory() {
@@ -227,6 +232,535 @@
return ephemeralKeyManager;
}
+ abstract SSLParameters getDefaultServerSSLParams();
+ abstract SSLParameters getDefaultClientSSLParams();
+ abstract SSLParameters getSupportedSSLParams();
+
+ // Get suported ProtoclList.
+ ProtocolList getSuportedProtocolList() {
+ if (supportedProtocolList == null) {
+ supportedProtocolList =
+ new ProtocolList(getSupportedSSLParams().getProtocols());
+ }
+
+ return supportedProtocolList;
+ }
+
+ // Get default ProtoclList.
+ ProtocolList getDefaultProtocolList(boolean roleIsServer) {
+ if (roleIsServer) {
+ if (defaultServerProtocolList == null) {
+ defaultServerProtocolList = new ProtocolList(
+ getDefaultServerSSLParams().getProtocols());
+ }
+
+ return defaultServerProtocolList;
+ } else {
+ if (defaultClientProtocolList == null) {
+ defaultClientProtocolList = new ProtocolList(
+ getDefaultClientSSLParams().getProtocols());
+ }
+
+ return defaultClientProtocolList;
+ }
+ }
+
+ // Get suported CipherSuiteList.
+ CipherSuiteList getSuportedCipherSuiteList() {
+ // Clear cache of available ciphersuites.
+ clearAvailableCache();
+
+ if (supportedCipherSuiteList == null) {
+ supportedCipherSuiteList =
+ getApplicableCipherSuiteList(getSuportedProtocolList(), false);
+ }
+
+ return supportedCipherSuiteList;
+ }
+
+ // Get default CipherSuiteList.
+ CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
+ // Clear cache of available ciphersuites.
+ clearAvailableCache();
+
+ if (roleIsServer) {
+ if (defaultServerCipherSuiteList == null) {
+ defaultServerCipherSuiteList = getApplicableCipherSuiteList(
+ getDefaultProtocolList(true), true);
+ }
+
+ return defaultServerCipherSuiteList;
+ } else {
+ if (defaultClientCipherSuiteList == null) {
+ defaultClientCipherSuiteList = getApplicableCipherSuiteList(
+ getDefaultProtocolList(false), true);
+ }
+
+ return defaultClientCipherSuiteList;
+ }
+ }
+
+ /**
+ * Return whether a protocol list is the original default enabled
+ * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
+ */
+ boolean isDefaultProtocolList(ProtocolList protocols) {
+ return (protocols == defaultServerProtocolList) ||
+ (protocols == defaultClientProtocolList);
+ }
+
+
+ /*
+ * Return the list of all available CipherSuites with a priority of
+ * minPriority or above.
+ */
+ private CipherSuiteList getApplicableCipherSuiteList(
+ ProtocolList protocols, boolean onlyEnabled) {
+
+ int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
+ if (onlyEnabled) {
+ minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
+ }
+
+ Collection<CipherSuite> allowedCipherSuites =
+ CipherSuite.allowedCipherSuites();
+
+ ArrayList<CipherSuite> suites = new ArrayList<>();
+ if (!(protocols.collection().isEmpty()) &&
+ protocols.min.v != ProtocolVersion.NONE.v) {
+ for (CipherSuite suite : allowedCipherSuites) {
+ if (suite.allowed == false || suite.priority < minPriority) {
+ continue;
+ }
+
+ if (suite.isAvailable() &&
+ suite.obsoleted > protocols.min.v &&
+ suite.supported <= protocols.max.v) {
+ if (defaultAlgorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+ suite.name, null)) {
+ suites.add(suite);
+ }
+ } else if (debug != null &&
+ Debug.isOn("sslctx") && Debug.isOn("verbose")) {
+ if (suite.obsoleted <= protocols.min.v) {
+ System.out.println(
+ "Ignoring obsoleted cipher suite: " + suite);
+ } else if (suite.supported > protocols.max.v) {
+ System.out.println(
+ "Ignoring unsupported cipher suite: " + suite);
+ } else {
+ System.out.println(
+ "Ignoring unavailable cipher suite: " + suite);
+ }
+ }
+ }
+ }
+
+ return new CipherSuiteList(suites);
+ }
+
+ /**
+ * Clear cache of available ciphersuites. If we support all ciphers
+ * internally, there is no need to clear the cache and calling this
+ * method has no effect.
+ */
+ synchronized void clearAvailableCache() {
+ if (CipherSuite.DYNAMIC_AVAILABILITY) {
+ supportedCipherSuiteList = null;
+ defaultServerCipherSuiteList = null;
+ defaultClientCipherSuiteList = null;
+ CipherSuite.BulkCipher.clearAvailableCache();
+ JsseJce.clearEcAvailable();
+ }
+ }
+
+ /*
+ * The SSLContext implementation for TLS/SSL algorithm
+ *
+ * SSL/TLS protocols specify the forward compatibility and version
+ * roll-back attack protections, however, a number of SSL/TLS server
+ * vendors did not implement these aspects properly, and some current
+ * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.
+ *
+ * Considering above interoperability issues, SunJSSE will not set
+ * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default.
+ *
+ * For SSL/TLS servers, there is no such interoperability issues as
+ * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the
+ * enabled protocols for server by default.
+ *
+ * We may change the behavior when popular TLS/SSL vendors support TLS
+ * forward compatibility properly.
+ *
+ * SSLv2Hello is no longer necessary. This interoperability option was
+ * put in place in the late 90's when SSLv3/TLS1.0 were relatively new
+ * and there were a fair number of SSLv2-only servers deployed. Because
+ * of the security issues in SSLv2, it is rarely (if ever) used, as
+ * deployments should now be using SSLv3 and TLSv1.
+ *
+ * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello
+ * by default. Applications still can use it by enabling SSLv2Hello with
+ * the series of setEnabledProtocols APIs.
+ */
+
+ /*
+ * The conservative SSLContext implementation for TLS, SSL, SSLv3 and
+ * TLS10 algorithm.
+ *
+ * This is a super class of DefaultSSLContext and TLS10Context.
+ *
+ * @see SSLContext
+ */
+ private static class ConservativeSSLContext extends SSLContextImpl {
+ // parameters
+ private static SSLParameters defaultServerSSLParams;
+ private static SSLParameters defaultClientSSLParams;
+ private static SSLParameters supportedSSLParams;
+
+ static {
+ if (SunJSSE.isFIPS()) {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name
+ });
+
+ } else {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL20Hello.name,
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name
+ });
+ }
+ }
+
+ SSLParameters getDefaultServerSSLParams() {
+ return defaultServerSSLParams;
+ }
+
+ SSLParameters getDefaultClientSSLParams() {
+ return defaultClientSSLParams;
+ }
+
+ SSLParameters getSupportedSSLParams() {
+ return supportedSSLParams;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for default algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class DefaultSSLContext extends ConservativeSSLContext {
+ private static final String NONE = "NONE";
+ private static final String P11KEYSTORE = "PKCS11";
+
+ private static volatile SSLContextImpl defaultImpl;
+
+ private static TrustManager[] defaultTrustManagers;
+ private static KeyManager[] defaultKeyManagers;
+
+ public DefaultSSLContext() throws Exception {
+ try {
+ super.engineInit(getDefaultKeyManager(),
+ getDefaultTrustManager(), null);
+ } catch (Exception e) {
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("default context init failed: " + e);
+ }
+ throw e;
+ }
+
+ if (defaultImpl == null) {
+ defaultImpl = this;
+ }
+ }
+
+ protected void engineInit(KeyManager[] km, TrustManager[] tm,
+ SecureRandom sr) throws KeyManagementException {
+ throw new KeyManagementException
+ ("Default SSLContext is initialized automatically");
+ }
+
+ static synchronized SSLContextImpl getDefaultImpl() throws Exception {
+ if (defaultImpl == null) {
+ new DefaultSSLContext();
+ }
+ return defaultImpl;
+ }
+
+ private static synchronized TrustManager[] getDefaultTrustManager()
+ throws Exception {
+ if (defaultTrustManagers != null) {
+ return defaultTrustManagers;
+ }
+
+ KeyStore ks =
+ TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ks);
+ defaultTrustManagers = tmf.getTrustManagers();
+ return defaultTrustManagers;
+ }
+
+ private static synchronized KeyManager[] getDefaultKeyManager()
+ throws Exception {
+ if (defaultKeyManagers != null) {
+ return defaultKeyManagers;
+ }
+
+ final Map<String,String> props = new HashMap<>();
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Object>() {
+ public Object run() throws Exception {
+ props.put("keyStore", System.getProperty(
+ "javax.net.ssl.keyStore", ""));
+ props.put("keyStoreType", System.getProperty(
+ "javax.net.ssl.keyStoreType",
+ KeyStore.getDefaultType()));
+ props.put("keyStoreProvider", System.getProperty(
+ "javax.net.ssl.keyStoreProvider", ""));
+ props.put("keyStorePasswd", System.getProperty(
+ "javax.net.ssl.keyStorePassword", ""));
+ return null;
+ }
+ });
+
+ final String defaultKeyStore = props.get("keyStore");
+ String defaultKeyStoreType = props.get("keyStoreType");
+ String defaultKeyStoreProvider = props.get("keyStoreProvider");
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("keyStore is : " + defaultKeyStore);
+ System.out.println("keyStore type is : " +
+ defaultKeyStoreType);
+ System.out.println("keyStore provider is : " +
+ defaultKeyStoreProvider);
+ }
+
+ if (P11KEYSTORE.equals(defaultKeyStoreType) &&
+ !NONE.equals(defaultKeyStore)) {
+ throw new IllegalArgumentException("if keyStoreType is "
+ + P11KEYSTORE + ", then keyStore must be " + NONE);
+ }
+
+ FileInputStream fs = null;
+ if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) {
+ fs = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<FileInputStream>() {
+ public FileInputStream run() throws Exception {
+ return new FileInputStream(defaultKeyStore);
+ }
+ });
+ }
+
+ String defaultKeyStorePassword = props.get("keyStorePasswd");
+ char[] passwd = null;
+ if (defaultKeyStorePassword.length() != 0) {
+ passwd = defaultKeyStorePassword.toCharArray();
+ }
+
+ /**
+ * Try to initialize key store.
+ */
+ KeyStore ks = null;
+ if ((defaultKeyStoreType.length()) != 0) {
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("init keystore");
+ }
+ if (defaultKeyStoreProvider.length() == 0) {
+ ks = KeyStore.getInstance(defaultKeyStoreType);
+ } else {
+ ks = KeyStore.getInstance(defaultKeyStoreType,
+ defaultKeyStoreProvider);
+ }
+
+ // if defaultKeyStore is NONE, fs will be null
+ ks.load(fs, passwd);
+ }
+ if (fs != null) {
+ fs.close();
+ fs = null;
+ }
+
+ /*
+ * Try to initialize key manager.
+ */
+ if (debug != null && Debug.isOn("defaultctx")) {
+ System.out.println("init keymanager of type " +
+ KeyManagerFactory.getDefaultAlgorithm());
+ }
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+
+ if (P11KEYSTORE.equals(defaultKeyStoreType)) {
+ kmf.init(ks, null); // do not pass key passwd if using token
+ } else {
+ kmf.init(ks, passwd);
+ }
+
+ defaultKeyManagers = kmf.getKeyManagers();
+ return defaultKeyManagers;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for TLS, SSL, SSLv3 and TLS10 algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class TLS10Context extends ConservativeSSLContext {
+ // use the default constructor and methods
+ }
+
+ /*
+ * The SSLContext implementation for TLS11 algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class TLS11Context extends SSLContextImpl {
+ // parameters
+ private static SSLParameters defaultServerSSLParams;
+ private static SSLParameters defaultClientSSLParams;
+ private static SSLParameters supportedSSLParams;
+
+ static {
+ if (SunJSSE.isFIPS()) {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name
+ });
+
+ } else {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL20Hello.name,
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name
+ });
+ }
+ }
+
+ SSLParameters getDefaultServerSSLParams() {
+ return defaultServerSSLParams;
+ }
+
+ SSLParameters getDefaultClientSSLParams() {
+ return defaultClientSSLParams;
+ }
+
+ SSLParameters getSupportedSSLParams() {
+ return supportedSSLParams;
+ }
+ }
+
+ /*
+ * The SSLContext implementation for TLS12 algorithm
+ *
+ * @see SSLContext
+ */
+ public static final class TLS12Context extends SSLContextImpl {
+ // parameters
+ private static SSLParameters defaultServerSSLParams;
+ private static SSLParameters defaultClientSSLParams;
+ private static SSLParameters supportedSSLParams;
+
+ static {
+ if (SunJSSE.isFIPS()) {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ } else {
+ supportedSSLParams = new SSLParameters();
+ supportedSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL20Hello.name,
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ defaultServerSSLParams = supportedSSLParams;
+
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(new String[] {
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+ }
+ }
+
+ SSLParameters getDefaultServerSSLParams() {
+ return defaultServerSSLParams;
+ }
+
+ SSLParameters getDefaultClientSSLParams() {
+ return defaultClientSSLParams;
+ }
+
+ SSLParameters getSupportedSSLParams() {
+ return supportedSSLParams;
+ }
+ }
+
}
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -374,8 +374,10 @@
clientVerifyData = new byte[0];
serverVerifyData = new byte[0];
- enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault(roleIsServer);
+ enabledCipherSuites =
+ sslContext.getDefaultCipherSuiteList(roleIsServer);
+ enabledProtocols =
+ sslContext.getDefaultProtocolList(roleIsServer);
wrapLock = new Object();
unwrapLock = new Object();
@@ -1883,8 +1885,8 @@
* change them to the corresponding default ones.
*/
if (roleIsServer != (!flag) &&
- ProtocolList.isDefaultProtocolList(enabledProtocols)) {
- enabledProtocols = ProtocolList.getDefault(!flag);
+ sslContext.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = sslContext.getDefaultProtocolList(!flag);
}
roleIsServer = !flag;
@@ -1907,8 +1909,8 @@
* change them to the corresponding default ones.
*/
if (roleIsServer != (!flag) &&
- ProtocolList.isDefaultProtocolList(enabledProtocols)) {
- enabledProtocols = ProtocolList.getDefault(!flag);
+ sslContext.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = sslContext.getDefaultProtocolList(!flag);
}
roleIsServer = !flag;
@@ -1951,8 +1953,7 @@
* @return an array of cipher suite names
*/
public String[] getSupportedCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getSupported().toStringArray();
+ return sslContext.getSuportedCipherSuiteList().toStringArray();
}
/**
@@ -1992,7 +1993,7 @@
* @return an array of protocol names.
*/
public String[] getSupportedProtocols() {
- return ProtocolList.getSupported().toStringArray();
+ return sslContext.getSuportedProtocolList().toStringArray();
}
/**
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,7 @@
* java.security file is set.
*/
public SSLServerSocketFactoryImpl() throws Exception {
- this.context = DefaultSSLContextImpl.getDefaultImpl();
+ this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
}
/**
@@ -99,8 +99,7 @@
* is encrypted to provide confidentiality.
*/
public String[] getDefaultCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getDefault().toStringArray();
+ return context.getDefaultCipherSuiteList(true).toStringArray();
}
/**
@@ -114,8 +113,7 @@
* @return an array of cipher suite names
*/
public String[] getSupportedCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getSupported().toStringArray();
+ return context.getSuportedCipherSuiteList().toStringArray();
}
}
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,8 +153,8 @@
throw new SSLException("No Authentication context given");
}
sslContext = context;
- enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault(true);
+ enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true);
+ enabledProtocols = sslContext.getDefaultProtocolList(true);
}
/**
@@ -168,8 +168,7 @@
* @return an array of cipher suite names
*/
public String[] getSupportedCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getSupported().toStringArray();
+ return sslContext.getSuportedCipherSuiteList().toStringArray();
}
/**
@@ -194,7 +193,7 @@
}
public String[] getSupportedProtocols() {
- return ProtocolList.getSupported().toStringArray();
+ return sslContext.getSuportedProtocolList().toStringArray();
}
/**
@@ -253,8 +252,8 @@
* change them to the corresponding default ones.
*/
if (useServerMode != (!flag) &&
- ProtocolList.isDefaultProtocolList(enabledProtocols)) {
- enabledProtocols = ProtocolList.getDefault(!flag);
+ sslContext.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = sslContext.getDefaultProtocolList(!flag);
}
useServerMode = !flag;
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* 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,20 +42,18 @@
*
* @author David Brownell
*/
-final
-public class SSLSocketFactoryImpl extends SSLSocketFactory
-{
+final public class SSLSocketFactoryImpl extends SSLSocketFactory {
+
private static SSLContextImpl defaultContext;
private SSLContextImpl context;
-
/**
* Constructor used to instantiate the default factory. This method is
* only called if the old "ssl.SocketFactory.provider" property in the
* java.security file is set.
*/
public SSLSocketFactoryImpl() throws Exception {
- this.context = DefaultSSLContextImpl.getDefaultImpl();
+ this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl();
}
/**
@@ -167,11 +165,9 @@
* is encrypted to provide confidentiality.
*/
public String[] getDefaultCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getDefault().toStringArray();
+ return context.getDefaultCipherSuiteList(false).toStringArray();
}
-
/**
* Returns the names of the cipher suites which could be enabled for use
* on an SSL connection. Normally, only a subset of these will actually
@@ -181,7 +177,6 @@
* certain kinds of certificates to use certain cipher suites.
*/
public String[] getSupportedCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getSupported().toStringArray();
+ return context.getSuportedCipherSuiteList().toStringArray();
}
}
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -562,8 +562,11 @@
clientVerifyData = new byte[0];
serverVerifyData = new byte[0];
- enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault(roleIsServer);
+ enabledCipherSuites =
+ sslContext.getDefaultCipherSuiteList(roleIsServer);
+ enabledProtocols =
+ sslContext.getDefaultProtocolList(roleIsServer);
+
inrec = null;
// save the acc
@@ -2170,8 +2173,8 @@
* change them to the corresponding default ones.
*/
if (roleIsServer != (!flag) &&
- ProtocolList.isDefaultProtocolList(enabledProtocols)) {
- enabledProtocols = ProtocolList.getDefault(!flag);
+ sslContext.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = sslContext.getDefaultProtocolList(!flag);
}
roleIsServer = !flag;
break;
@@ -2192,8 +2195,8 @@
* change them to the corresponding default ones.
*/
if (roleIsServer != (!flag) &&
- ProtocolList.isDefaultProtocolList(enabledProtocols)) {
- enabledProtocols = ProtocolList.getDefault(!flag);
+ sslContext.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = sslContext.getDefaultProtocolList(!flag);
}
roleIsServer = !flag;
connectionState = cs_START;
@@ -2230,8 +2233,7 @@
* @return an array of cipher suite names
*/
public String[] getSupportedCipherSuites() {
- CipherSuiteList.clearAvailableCache();
- return CipherSuiteList.getSupported().toStringArray();
+ return sslContext.getSuportedCipherSuiteList().toStringArray();
}
/**
@@ -2271,7 +2273,7 @@
* @return an array of protocol names.
*/
public String[] getSupportedProtocols() {
- return ProtocolList.getSupported().toStringArray();
+ return sslContext.getSuportedProtocolList().toStringArray();
}
/**
--- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java Tue Apr 12 14:23:03 2011 -0700
@@ -204,22 +204,21 @@
put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX");
put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
put("Alg.Alias.TrustManagerFactory.X.509", "PKIX");
+
+ put("SSLContext.TLSv1",
+ "sun.security.ssl.SSLContextImpl$TLS10Context");
+ put("Alg.Alias.SSLContext.TLS", "TLSv1");
if (isfips == false) {
- put("SSLContext.SSL",
- "sun.security.ssl.SSLContextImpl");
- put("SSLContext.SSLv3",
- "sun.security.ssl.SSLContextImpl");
+ put("Alg.Alias.SSLContext.SSL", "TLSv1");
+ put("Alg.Alias.SSLContext.SSLv3", "TLSv1");
}
- put("SSLContext.TLS",
- "sun.security.ssl.SSLContextImpl");
- put("SSLContext.TLSv1",
- "sun.security.ssl.SSLContextImpl");
+
put("SSLContext.TLSv1.1",
- "sun.security.ssl.SSLContextImpl");
+ "sun.security.ssl.SSLContextImpl$TLS11Context");
put("SSLContext.TLSv1.2",
- "sun.security.ssl.SSLContextImpl");
+ "sun.security.ssl.SSLContextImpl$TLS12Context");
put("SSLContext.Default",
- "sun.security.ssl.DefaultSSLContextImpl");
+ "sun.security.ssl.SSLContextImpl$DefaultSSLContext");
/*
* KeyStore
--- a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -191,8 +191,8 @@
*
*
*/
- public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners,
- Hashtable<String, CodeSigner[]> sigFileSigners)
+ public CodeSigner[] verify(Map<String, CodeSigner[]> verifiedSigners,
+ Map<String, CodeSigner[]> sigFileSigners)
throws JarException
{
if (skip) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+/**
+ * This class provides streaming mode reading of manifest files.
+ * Used by {@link SignatureFileVerifier}.
+ */
+class SignatureFileManifest extends Manifest {
+
+ /*
+ * Reading a manifest into this object by calling update(byte[]) on chunks.
+ * During the reading, the bytes are saved in (@code current} until a line
+ * is complete and the key-value pair is saved in {@code currentAttr}. When
+ * a section is complete, {@code consumeAttr} is called to merge
+ * {@code currentAttr} into main attributes or a named entry.
+ */
+
+ // Internal state during update() style reading
+ // 0. not in update mode
+ // 1, in update mode but main attributes not completed yet
+ // 2. main attributes completed, still reading the entries
+ private int state = 0;
+
+ // The partial line read
+ private byte[] current;
+
+ // Number of bytes in current
+ private int currentPos = 0;
+
+ // The current Attribute
+ private Attributes currentAttr;
+
+ /**
+ * Reads a manifest in chunks.
+ * <p>
+ * This method must be called in a row, reading chunks from a single
+ * manifest file by order. After all chunks are read, caller must call
+ * {@code update(null)} to fully consume the manifest.
+ * <p>
+ * The entry names and attributes read will be merged in with the current
+ * manifest entries. The {@link #read} method cannot be called inside a
+ * row of update calls.
+ * <p>
+ * Along with the calls, caller can call {@link #getMainAttributes()},
+ * {@link #getAttributes(java.lang.String)} or {@link #getEntries()}
+ * to get already available contents. However, in order not to return
+ * partial result, when the main attributes in the new manifest is not
+ * consumed completely, {@link #getMainAttributes()} throws an
+ * {@code IllegalStateException}. When a certain named entry is not
+ * consumed completely, {@link #getAttributes(java.lang.String)}
+ * returns the old {@code Attributes} for the name (if it exists).
+ *
+ * @param data null for last call, otherwise, feeding chunks
+ * @param offset offset into data to begin read
+ * @param length length of data after offset to read
+ * @exception IOException if an I/O error has occurred
+ * @exception IllegalStateException if {@code update(null)} is called
+ * without any previous {@code update(non-null)} call
+ */
+ public void update(byte[] data, int offset, int length) throws IOException {
+
+ // The last call
+ if (data == null) {
+ if (state == 0) {
+ throw new IllegalStateException("No data to update");
+ }
+ // We accept manifest not ended with \n or \n\n
+ if (hasLastByte()) {
+ consumeCurrent();
+ }
+ // We accept empty lines at the end
+ if (!currentAttr.isEmpty()) {
+ consumeAttr();
+ }
+ state = 0; // back to non-update state
+ current = null;
+ currentAttr = null;
+ return;
+ }
+
+ // The first call
+ if (state == 0) {
+ current = new byte[1024];
+ currentAttr = super.getMainAttributes(); // the main attribute
+ state = 1;
+ }
+
+ int end = offset + length;
+
+ while (offset < end) {
+ switch (data[offset]) {
+ case '\r':
+ break; // always skip
+ case '\n':
+ if (hasLastByte() && lastByte() == '\n') { // new section
+ consumeCurrent();
+ consumeAttr();
+ if (state == 1) {
+ state = 2;
+ }
+ currentAttr = new Attributes(2);
+ } else {
+ if (hasLastByte()) {
+ // save \n into current but do not parse,
+ // there might be a continuation later
+ ensureCapacity();
+ current[currentPos++] = data[offset];
+ } else if (state == 1) {
+ // there can be multiple empty lines between
+ // sections, but cannot be at the beginning
+ throw new IOException("invalid manifest format");
+ }
+ }
+ break;
+ case ' ':
+ if (!hasLastByte()) {
+ throw new IOException("invalid manifest format");
+ } else if (lastByte() == '\n') {
+ currentPos--; // continuation, remove last \n
+ } else { // a very normal ' '
+ ensureCapacity();
+ current[currentPos++] = data[offset];
+ }
+ break;
+ default:
+ if (hasLastByte() && lastByte() == '\n') {
+ // The start of a new pair, not continuation
+ consumeCurrent(); // the last line read
+ }
+ ensureCapacity();
+ current[currentPos++] = data[offset];
+ break;
+ }
+ offset++;
+ }
+ }
+
+ /**
+ * Returns the main Attributes for the Manifest.
+ * @exception IllegalStateException the main attributes is being read
+ * @return the main Attributes for the Manifest
+ */
+ public Attributes getMainAttributes() {
+ if (state == 1) {
+ throw new IllegalStateException();
+ }
+ return super.getMainAttributes();
+ }
+
+ /**
+ * Reads the Manifest from the specified InputStream. The entry
+ * names and attributes read will be merged in with the current
+ * manifest entries.
+ *
+ * @param is the input stream
+ * @exception IOException if an I/O error has occurred
+ * @exception IllegalStateException if called between two {@link #update}
+ * calls
+ */
+ public void read(InputStream is) throws IOException {
+ if (state != 0) {
+ throw new IllegalStateException("Cannot call read between updates");
+ }
+ super.read(is);
+ }
+
+ /*
+ * ---------- Helper methods -----------------
+ */
+
+ private void ensureCapacity() {
+ if (currentPos >= current.length-1) {
+ current = Arrays.copyOf(current, current.length*2);
+ }
+ }
+
+ private boolean hasLastByte() {
+ return currentPos > 0;
+ }
+
+ private byte lastByte() {
+ return current[currentPos-1];
+ }
+
+ // Parse current as key:value and save into currentAttr.
+ // There MUST be something inside current.
+ private void consumeCurrent() throws IOException {
+ // current normally has a \n end, except for the last line
+ if (current[currentPos-1] == '\n') currentPos--;
+ for (int i=0; i<currentPos; i++) {
+ if (current[i] == ':') {
+ String key = new String(current, 0, 0, i);
+ i++;
+ while (i < currentPos && current[i] == ' ') { i++; }
+ String value = new String(current, i, currentPos-i, "UTF-8");
+ currentAttr.putValue(key, value);
+ currentPos = 0;
+ return;
+ }
+ }
+ throw new IOException("invalid header field");
+ }
+
+ // Merge currentAttr into Manifest
+ private void consumeAttr() throws IOException {
+ // Only needed for named entries. For the main attribute, key/value
+ // is added into attr directly, but since getMainAttributes() throws
+ // an exception, the partial data is not leaked.
+ if (state != 1) {
+ String name = currentAttr.getValue("Name");
+ if (name != null) {
+ currentAttr.remove(new Attributes.Name("Name"));
+ Attributes old = getAttributes(name);
+ if (old != null) old.putAll(currentAttr);
+ else getEntries().put(name, currentAttr);
+ } else {
+ throw new IOException("invalid manifest format");
+ }
+ }
+ }
+}
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue Apr 12 14:23:03 2011 -0700
@@ -55,8 +55,8 @@
/** the PKCS7 block for this .DSA/.RSA/.EC file */
private PKCS7 block;
- /** the raw bytes of the .SF file */
- private byte sfBytes[];
+ // the content of the raw .SF file as an InputStream
+ private InputStream sfStream;
/** the name of the signature block file, uppercased and without
* the extension (.DSA/.RSA/.EC)
@@ -66,6 +66,9 @@
/** the ManifestDigester */
private ManifestDigester md;
+ /** The MANIFEST.MF */
+ private Manifest man;
+
/** cache of created MessageDigest objects */
private HashMap<String, MessageDigest> createdDigests;
@@ -83,6 +86,7 @@
* @param rawBytes the raw bytes of the signature block file
*/
public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache,
+ Manifest man,
ManifestDigester md,
String name,
byte rawBytes[])
@@ -94,13 +98,18 @@
try {
obj = Providers.startJarVerification();
block = new PKCS7(rawBytes);
- sfBytes = block.getContentInfo().getData();
+ byte[] contentData = block.getContentInfo().getData();
+ if (contentData != null) {
+ sfStream = new ByteArrayInputStream(contentData);
+ }
certificateFactory = CertificateFactory.getInstance("X509");
} finally {
Providers.stopJarVerification(obj);
}
this.name = name.substring(0, name.lastIndexOf("."))
.toUpperCase(Locale.ENGLISH);
+
+ this.man = man;
this.md = md;
this.signerCache = signerCache;
}
@@ -108,31 +117,13 @@
/**
* returns true if we need the .SF file
*/
- public boolean needSignatureFileBytes()
+ public boolean needSignatureFile()
{
-
- return sfBytes == null;
+ return sfStream == null;
}
-
- /**
- * returns true if we need this .SF file.
- *
- * @param name the name of the .SF file without the extension
- *
- */
- public boolean needSignatureFile(String name)
- {
- return this.name.equalsIgnoreCase(name);
- }
-
- /**
- * used to set the raw bytes of the .SF file when it
- * is external to the signature block file.
- */
- public void setSignatureFile(byte sfBytes[])
- {
- this.sfBytes = sfBytes;
+ public void setSignatureFile(InputStream ins) {
+ this.sfStream = ins;
}
/**
@@ -145,12 +136,18 @@
* Signature File or PKCS7 block file name
*/
public static boolean isBlockOrSF(String s) {
- // we currently only support DSA and RSA PKCS7 blocks
- if (s.endsWith(".SF") || s.endsWith(".DSA") ||
- s.endsWith(".RSA") || s.endsWith(".EC")) {
- return true;
- }
- return false;
+ return s.endsWith(".SF") || isBlock(s);
+ }
+
+ /**
+ * Utility method used by JarVerifier to determine PKCS7 block
+ * files names that are supported
+ *
+ * @param s file name
+ * @return true if the input file name is a PKCS7 block file name
+ */
+ public static boolean isBlock(String s) {
+ return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC");
}
/** get digest from cache */
@@ -180,7 +177,7 @@
*
*
*/
- public void process(Hashtable<String, CodeSigner[]> signers,
+ public void process(Map<String, CodeSigner[]> signers,
List manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
@@ -197,31 +194,86 @@
}
- private void processImpl(Hashtable<String, CodeSigner[]> signers,
+ private void processImpl(Map<String, CodeSigner[]> signers,
List manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
- Manifest sf = new Manifest();
- sf.read(new ByteArrayInputStream(sfBytes));
+ SignatureFileManifest sf = new SignatureFileManifest();
+ InputStream ins = sfStream;
- String version =
- sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
+ byte[] buffer = new byte[4096];
+ int sLen = block.getSignerInfos().length;
+ boolean mainOK = false; // main attributes of SF is available...
+ boolean manifestSigned = false; // and it matches MANIFEST.MF
+ BASE64Decoder decoder = new BASE64Decoder();
- if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
- // XXX: should this be an exception?
- // for now we just ignore this signature file
- return;
+ PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen];
+ for (int i=0; i<sLen; i++) {
+ pvs[i] = PKCS7.PKCS7Verifier.from(block, block.getSignerInfos()[i]);
}
- SignerInfo[] infos = block.verify(sfBytes);
+ /*
+ * Verify SF in streaming mode. The chunks of the file are fed into
+ * the Manifest object sf and all PKCS7Verifiers. As soon as the main
+ * attributes is available, we'll check if manifestSigned is true. If
+ * yes, there is no need to fill in sf's entries field, since it should
+ * be identical to entries in man.
+ */
+ while (true) {
+ int len = ins.read(buffer);
+ if (len < 0) {
+ if (!manifestSigned) {
+ sf.update(null, 0, 0);
+ }
+ break;
+ } else {
+ for (int i=0; i<sLen; i++) {
+ if (pvs[i] != null) pvs[i].update(buffer, 0, len);
+ }
+ // Continue reading if verifyManifestHash fails (or, the
+ // main attributes is not available yet)
+ if (!manifestSigned) {
+ sf.update(buffer, 0, len);
+ if (!mainOK) {
+ try {
+ Attributes attr = sf.getMainAttributes();
+ String version = attr.getValue(
+ Attributes.Name.SIGNATURE_VERSION);
- if (infos == null) {
+ if ((version == null) ||
+ !(version.equalsIgnoreCase("1.0"))) {
+ // XXX: should this be an exception?
+ // for now we just ignore this signature file
+ return;
+ }
+
+ mainOK = true;
+ manifestSigned = verifyManifestHash(
+ sf, md, decoder, manifestDigests);
+ } catch (IllegalStateException ise) {
+ // main attributes not available yet
+ }
+ }
+ }
+ }
+ }
+ List<SignerInfo> intResult = new ArrayList<>(sLen);
+ for (int i = 0; i < sLen; i++) {
+ if (pvs[i] != null) {
+ SignerInfo signerInfo = pvs[i].verify();
+ if (signerInfo != null) {
+ intResult.add(signerInfo);
+ }
+ }
+ }
+ if (intResult.isEmpty()) {
throw new SecurityException("cannot verify signature block file " +
name);
}
- BASE64Decoder decoder = new BASE64Decoder();
+ SignerInfo[] infos =
+ intResult.toArray(new SignerInfo[intResult.size()]);
CodeSigner[] newSigners = getSigners(infos, block);
@@ -229,26 +281,37 @@
if (newSigners == null)
return;
- Iterator<Map.Entry<String,Attributes>> entries =
- sf.getEntries().entrySet().iterator();
-
- // see if we can verify the whole manifest first
- boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests);
-
// verify manifest main attributes
if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) {
throw new SecurityException
("Invalid signature file digest for Manifest main attributes");
}
- // go through each section in the signature file
+ Iterator<Map.Entry<String,Attributes>> entries;
+
+ if (manifestSigned) {
+ if (debug != null) {
+ debug.println("full manifest signature match, "
+ + "update signer info from MANIFEST.MF");
+ }
+ entries = man.getEntries().entrySet().iterator();
+ } else {
+ if (debug != null) {
+ debug.println("full manifest signature unmatch, "
+ + "update signer info from SF file");
+ }
+ entries = sf.getEntries().entrySet().iterator();
+ }
+
+ // go through each section
+
while(entries.hasNext()) {
Map.Entry<String,Attributes> e = entries.next();
String name = e.getKey();
if (manifestSigned ||
- (verifySection(e.getValue(), name, md, decoder))) {
+ (verifySection(e.getValue(), name, md, decoder))) {
if (name.startsWith("./"))
name = name.substring(2);
@@ -593,7 +656,6 @@
if (set == subset)
return true;
- boolean match;
for (int i = 0; i < subset.length; i++) {
if (!contains(set, subset[i]))
return false;
@@ -613,8 +675,6 @@
if ((oldSigners == null) && (signers == newSigners))
return true;
- boolean match;
-
// make sure all oldSigners are in signers
if ((oldSigners != null) && !isSubSet(oldSigners, signers))
return false;
@@ -638,7 +698,7 @@
}
void updateSigners(CodeSigner[] newSigners,
- Hashtable<String, CodeSigner[]> signers, String name) {
+ Map<String, CodeSigner[]> signers, String name) {
CodeSigner[] oldSigners = signers.get(name);
--- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java Tue Apr 12 14:23:03 2011 -0700
@@ -479,7 +479,7 @@
String zi = System.getProperty("java.home") +
File.separator + "lib" + File.separator + "zi";
try {
- zi = FileSystems.getDefault().getPath(zi).toRealPath(true).toString();
+ zi = FileSystems.getDefault().getPath(zi).toRealPath().toString();
} catch(Exception e) {
}
return zi;
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Tue Apr 12 14:23:03 2011 -0700
@@ -99,7 +99,7 @@
synchronized(filesystems) {
Path realPath = null;
if (ensureFile(path)) {
- realPath = path.toRealPath(true);
+ realPath = path.toRealPath();
if (filesystems.containsKey(realPath))
throw new FileSystemAlreadyExistsException();
}
@@ -154,7 +154,7 @@
synchronized (filesystems) {
ZipFileSystem zipfs = null;
try {
- zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
+ zipfs = filesystems.get(uriToPath(uri).toRealPath());
} catch (IOException x) {
// ignore the ioe from toRealPath(), return FSNFE
}
@@ -310,7 +310,7 @@
//////////////////////////////////////////////////////////////
void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException {
synchronized (filesystems) {
- zfpath = zfpath.toRealPath(true);
+ zfpath = zfpath.toRealPath();
if (filesystems.get(zfpath) == zfs)
filesystems.remove(zfpath);
}
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Tue Apr 12 14:23:03 2011 -0700
@@ -150,7 +150,7 @@
}
@Override
- public ZipPath toRealPath(boolean resolveLinks) throws IOException {
+ public ZipPath toRealPath(LinkOption... options) throws IOException {
ZipPath realPath = new ZipPath(zfs, getResolvedPath()).toAbsolutePath();
realPath.checkAccess();
return realPath;
--- a/jdk/src/share/native/java/util/zip/Deflater.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/native/java/util/zip/Deflater.c Tue Apr 12 14:23:03 2011 -0700
@@ -129,34 +129,28 @@
if ((*env)->GetBooleanField(env, this, setParamsID)) {
int level = (*env)->GetIntField(env, this, levelID);
int strategy = (*env)->GetIntField(env, this, strategyID);
-
- in_buf = (jbyte *) malloc(this_len);
- if (in_buf == 0) {
+ in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+ if (in_buf == NULL) {
// Throw OOME only when length is not zero
if (this_len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
- (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
- out_buf = (jbyte *) malloc(len);
- if (out_buf == 0) {
- free(in_buf);
+ out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+ if (out_buf == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
if (len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
- strm->next_in = (Bytef *) in_buf;
- strm->next_out = (Bytef *) out_buf;
+ strm->next_in = (Bytef *) (in_buf + this_off);
+ strm->next_out = (Bytef *) (out_buf + off);
strm->avail_in = this_len;
strm->avail_out = len;
res = deflateParams(strm, level, strategy);
-
- if (res == Z_OK) {
- (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
- }
- free(out_buf);
- free(in_buf);
+ (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
switch (res) {
case Z_OK:
@@ -174,33 +168,28 @@
}
} else {
jboolean finish = (*env)->GetBooleanField(env, this, finishID);
- in_buf = (jbyte *) malloc(this_len);
- if (in_buf == 0) {
+ in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+ if (in_buf == NULL) {
if (this_len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
- (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
-
- out_buf = (jbyte *) malloc(len);
- if (out_buf == 0) {
- free(in_buf);
+ out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+ if (out_buf == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
if (len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
+
return 0;
}
- strm->next_in = (Bytef *) in_buf;
- strm->next_out = (Bytef *) out_buf;
+ strm->next_in = (Bytef *) (in_buf + this_off);
+ strm->next_out = (Bytef *) (out_buf + off);
strm->avail_in = this_len;
strm->avail_out = len;
res = deflate(strm, finish ? Z_FINISH : flush);
-
- if (res == Z_STREAM_END || res == Z_OK) {
- (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
- }
- free(out_buf);
- free(in_buf);
+ (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
switch (res) {
case Z_STREAM_END:
--- a/jdk/src/share/native/java/util/zip/Inflater.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/share/native/java/util/zip/Inflater.c Tue Apr 12 14:23:03 2011 -0700
@@ -38,8 +38,6 @@
#include "zlib.h"
#include "java_util_zip_Inflater.h"
-#define MIN2(x, y) ((x) < (y) ? (x) : (y))
-
#define ThrowDataFormatException(env, msg) \
JNU_ThrowByName(env, "java/util/zip/DataFormatException", msg)
@@ -111,71 +109,50 @@
jarray b, jint off, jint len)
{
z_stream *strm = jlong_to_ptr(addr);
-
jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
jint this_off = (*env)->GetIntField(env, this, offID);
jint this_len = (*env)->GetIntField(env, this, lenID);
+
jbyte *in_buf;
jbyte *out_buf;
int ret;
- /*
- * Avoid excess copying.
- * zlib stream usually has a few bytes of overhead for header info
- * (depends on the underlying data)
- *
- * (a) 5 bytes per 16KB
- * (b) 6 bytes for entire stream
- * (c) 4 bytes for gzip header
- * (d) 2 bytes for crc
- *
- * Use 20 bytes as the "safe cutoff" number.
- */
- jint in_len = MIN2(this_len, len + 20);
- jint consumed;
- in_buf = (jbyte *) malloc(in_len);
- if (in_buf == 0) {
- if (in_len != 0)
+ in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
+ if (in_buf == NULL) {
+ if (this_len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
- (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf);
-
- out_buf = (jbyte *) malloc(len);
- if (out_buf == 0) {
- free(in_buf);
+ out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
+ if (out_buf == NULL) {
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
if (len != 0)
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
-
- strm->next_in = (Bytef *) in_buf;
- strm->next_out = (Bytef *) out_buf;
- strm->avail_in = in_len;
+ strm->next_in = (Bytef *) (in_buf + this_off);
+ strm->next_out = (Bytef *) (out_buf + off);
+ strm->avail_in = this_len;
strm->avail_out = len;
ret = inflate(strm, Z_PARTIAL_FLUSH);
-
- if (ret == Z_STREAM_END || ret == Z_OK) {
- (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
- }
- free(out_buf);
- free(in_buf);
+ (*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
+ (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
switch (ret) {
case Z_STREAM_END:
(*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
/* fall through */
case Z_OK:
- consumed = in_len - strm->avail_in;
- (*env)->SetIntField(env, this, offID, this_off + consumed);
- (*env)->SetIntField(env, this, lenID, this_len - consumed);
+ this_off += this_len - strm->avail_in;
+ (*env)->SetIntField(env, this, offID, this_off);
+ (*env)->SetIntField(env, this, lenID, strm->avail_in);
return len - strm->avail_out;
case Z_NEED_DICT:
(*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
/* Might have consumed some input here! */
- consumed = in_len - strm->avail_in;
- (*env)->SetIntField(env, this, offID, this_off + consumed);
- (*env)->SetIntField(env, this, lenID, this_len - consumed);
+ this_off += this_len - strm->avail_in;
+ (*env)->SetIntField(env, this, offID, this_off);
+ (*env)->SetIntField(env, this, lenID, strm->avail_in);
return 0;
case Z_BUF_ERROR:
return 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/forkjoin/mergesort/MergeDemo.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Arrays;
+import java.util.Random;
+
+import static java.lang.Integer.parseInt;
+
+/**
+ * MergeExample is a class that runs a demo benchmark of the {@code ForkJoin} framework
+ * by benchmarking a {@link MergeSort} algorithm that is implemented using
+ * {@link java.util.concurrent.RecursiveAction}.
+ * The {@code ForkJoin} framework is setup with different parallelism levels
+ * and the sort is executed with arrays of different sizes to see the
+ * trade offs by using multiple threads for different sizes of the array.
+ */
+public class MergeDemo {
+ // Use a fixed seed to always get the same random values back
+ private final Random random = new Random(759123751834L);
+ private static final int ITERATIONS = 10;
+
+ /**
+ * Represents the formula {@code f(n) = start + (step * n)} for n = 0 & n < iterations
+ */
+ private static class Range {
+ private final int start;
+ private final int step;
+ private final int iterations;
+
+ private Range(int start, int step, int iterations) {
+ this.start = start;
+ this.step = step;
+ this.iterations = iterations;
+ }
+
+ /**
+ * Parses start, step and iterations from args
+ * @param args the string array containing the arguments
+ * @param start which element to start the start argument from
+ * @return the constructed range
+ */
+ public static Range parse(String[] args, int start) {
+ if (args.length < start + 3) {
+ throw new IllegalArgumentException("Too few elements in array");
+ }
+ return new Range(parseInt(args[start]), parseInt(args[start + 1]), parseInt(args[start + 2]));
+ }
+
+ public int get(int iteration) {
+ return start + (step * iteration);
+ }
+
+ public int getIterations() {
+ return iterations;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(start).append(" ").append(step).append(" ").append(iterations);
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Wraps the different parameters that is used when running the MergeExample.
+ * {@code sizes} represents the different array sizes
+ * {@code parallelism} represents the different parallelism levels
+ */
+ private static class Configuration {
+ private final Range sizes;
+ private final Range parallelism;
+
+ private final static Configuration defaultConfig = new Configuration(new Range(20000, 20000, 10),
+ new Range(2, 2, 10));
+
+ private Configuration(Range sizes, Range parallelism) {
+ this.sizes = sizes;
+ this.parallelism = parallelism;
+ }
+
+ /**
+ * Parses the arguments and attempts to create a configuration containing the
+ * parameters for creating the array sizes and parallelism sizes
+ * @param args the input arguments
+ * @return the configuration
+ */
+ public static Configuration parse(String[] args) {
+ if (args.length == 0) {
+ return defaultConfig;
+ } else {
+ try {
+ if (args.length == 6) {
+ return new Configuration(Range.parse(args, 0), Range.parse(args, 3));
+ }
+ } catch (NumberFormatException e) {
+ System.err.println("MergeExample: error: Argument was not a number.");
+ }
+ System.err.println("MergeExample <size start> <size step> <size steps> <parallel start> <parallel step>" +
+ " <parallel steps>");
+ System.err.println("example: MergeExample 20000 10000 3 1 1 4");
+ System.err.println("example: will run with arrays of sizes 20000, 30000, 40000" +
+ " and parallelism: 1, 2, 3, 4");
+ return null;
+ }
+ }
+
+ /**
+ * Creates an array for reporting the test result time in
+ * @return an array containing {@code sizes.iterations * parallelism.iterations} elements
+ */
+ private long[][] createTimesArray() {
+ return new long[sizes.getIterations()][parallelism.getIterations()];
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("");
+ if (this == defaultConfig) {
+ builder.append("Default configuration. ");
+ }
+ builder.append("Running with parameters: ");
+ builder.append(sizes);
+ builder.append(" ");
+ builder.append(parallelism);
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Generates an array of {@code elements} random elements
+ * @param elements the number of elements requested in the array
+ * @return an array of {@code elements} random elements
+ */
+ private int[] generateArray(int elements) {
+ int[] array = new int[elements];
+ for (int i = 0; i < elements; ++i) {
+ array[i] = random.nextInt();
+ }
+ return array;
+ }
+
+ /**
+ * Runs the test
+ * @param config contains the settings for the test
+ */
+ private void run(Configuration config) {
+ Range sizes = config.sizes;
+ Range parallelism = config.parallelism;
+
+ // Run a couple of sorts to make the JIT compile / optimize the code
+ // which should produce somewhat more fair times
+ warmup();
+
+ long[][] times = config.createTimesArray();
+
+ for (int size = 0; size < sizes.getIterations(); size++) {
+ runForSize(parallelism, sizes.get(size), times, size);
+ }
+
+ printResults(sizes, parallelism, times);
+ }
+
+ /**
+ * Prints the results as a table
+ * @param sizes the different sizes of the arrays
+ * @param parallelism the different parallelism levels used
+ * @param times the median times for the different sizes / parallelism
+ */
+ private void printResults(Range sizes, Range parallelism, long[][] times) {
+ System.out.println("Time in milliseconds. Y-axis: number of elements. X-axis parallelism used.");
+ long[] sums = new long[times[0].length];
+ System.out.format("%8s ", "");
+ for (int i = 0; i < times[0].length; i++) {
+ System.out.format("%4d ", parallelism.get(i));
+ }
+ System.out.println("");
+ for (int size = 0; size < sizes.getIterations(); size++) {
+ System.out.format("%8d: ", sizes.get(size));
+ for (int i = 0; i < times[size].length; i++) {
+ sums[i] += times[size][i];
+ System.out.format("%4d ", times[size][i]);
+ }
+ System.out.println("");
+ }
+ System.out.format("%8s: ", "Total");
+ for (long sum : sums) {
+ System.out.format("%4d ", sum);
+ }
+ System.out.println("");
+ }
+
+ private void runForSize(Range parallelism, int elements, long[][] times, int size) {
+ for (int step = 0; step < parallelism.getIterations(); step++) {
+ long time = runForParallelism(ITERATIONS, elements, parallelism.get(step));
+ times[size][step] = time;
+ }
+ }
+
+ /**
+ * Runs <i>iterations</i> number of test sorts of a random array of <i>element</i> length
+ * @param iterations number of iterations
+ * @param elements number of elements in the random array
+ * @param parallelism parallelism for the ForkJoin framework
+ * @return the median time of runs
+ */
+ private long runForParallelism(int iterations, int elements, int parallelism) {
+ MergeSort mergeSort = new MergeSort(parallelism);
+ long[] times = new long[iterations];
+
+ for (int i = 0; i < iterations; i++) {
+ // Suggest the VM to run a garbage collection to reduce the risk of getting one
+ // while running the test run
+ System.gc();
+ long start = System.currentTimeMillis();
+ mergeSort.sort(generateArray(elements));
+ times[i] = System.currentTimeMillis() - start;
+ }
+
+ return medianValue(times);
+ }
+
+ /**
+ * Calculates the median value of the array
+ * @param times array of times
+ * @return the median value
+ */
+ private long medianValue(long[] times) {
+ if (times.length == 0) {
+ throw new IllegalArgumentException("Empty array");
+ }
+ // Make a copy of times to avoid having side effects on the parameter value
+ Arrays.sort(times.clone());
+ long median = times[times.length / 2];
+ if (times.length > 1 && times.length % 2 != 0) {
+ median = (median + times[times.length / 2 + 1]) / 2;
+ }
+ return median;
+ }
+
+ /**
+ * Generates 1000 arrays of 1000 elements and sorts them as a warmup
+ */
+ private void warmup() {
+ MergeSort mergeSort = new MergeSort(Runtime.getRuntime().availableProcessors());
+ for (int i = 0; i < 1000; i++) {
+ mergeSort.sort(generateArray(1000));
+ }
+ }
+
+ public static void main(String[] args) {
+ Configuration configuration = Configuration.parse(args);
+ if (configuration == null) {
+ System.exit(1);
+ }
+ System.out.println(configuration);
+ new MergeDemo().run(configuration);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/forkjoin/mergesort/MergeSort.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.Arrays;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveAction;
+
+/**
+ * A class for sorting an array of {@code ints} in parallel.
+ * A {@code ForkJoinPool} is used for the parallelism, using the merge sort
+ * algorithm the array is split into halves and a new sub task is created
+ * for each part. Each sub task is dispatched to the {@code ForkJoinPool}
+ * which will schedule the task to a {@code Thread}.
+ * This happens until the size of the array is at most 2
+ * elements long. At this point the array is sorted using a simple compare
+ * and possibly a swap. The tasks then finish by using insert sort to
+ * merge the two just sorted arrays.
+ *
+ * The idea of this class is to demonstrate the usage of RecursiveAction not
+ * to implement the best possible parallel merge sort. This version creates
+ * a small array for each merge (creating a lot of objects), this could
+ * be avoided by keeping a single array.
+ */
+public class MergeSort {
+ private final ForkJoinPool pool;
+
+ private static class MergeSortTask extends RecursiveAction {
+ private final int[] array;
+ private final int low;
+ private final int high;
+ private static final int THRESHOLD = 8;
+
+ /**
+ * Creates a {@code MergeSortTask} containing the array and the bounds of the array
+ *
+ * @param array the array to sort
+ * @param low the lower element to start sorting at
+ * @param high the non-inclusive high element to sort to
+ */
+ protected MergeSortTask(int[] array, int low, int high) {
+ this.array = array;
+ this.low = low;
+ this.high = high;
+ }
+
+ @Override
+ protected void compute() {
+ if (high - low <= THRESHOLD) {
+ Arrays.sort(array, low, high);
+ } else {
+ int middle = low + ((high - low) >> 1);
+ // Execute the sub tasks and wait for them to finish
+ invokeAll(new MergeSortTask(array, low, middle), new MergeSortTask(array, middle, high));
+ // Then merge the results
+ merge(middle);
+ }
+ }
+
+ /**
+ * Merges the two sorted arrays this.low, middle - 1 and middle, this.high - 1
+ * @param middle the index in the array where the second sorted list begins
+ */
+ private void merge(int middle) {
+ if (array[middle - 1] < array[middle]) {
+ return; // the arrays are already correctly sorted, so we can skip the merge
+ }
+ int[] copy = new int[high - low];
+ System.arraycopy(array, low, copy, 0, copy.length);
+ int copyLow = 0;
+ int copyHigh = high - low;
+ int copyMiddle = middle - low;
+
+ for (int i = low, p = copyLow, q = copyMiddle; i < high; i++) {
+ if (q >= copyHigh || (p < copyMiddle && copy[p] < copy[q]) ) {
+ array[i] = copy[p++];
+ } else {
+ array[i] = copy[q++];
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a {@code MergeSort} containing a ForkJoinPool with the indicated parallelism level
+ * @param parallelism the parallelism level used
+ */
+ public MergeSort(int parallelism) {
+ pool = new ForkJoinPool(parallelism);
+ }
+
+ /**
+ * Sorts all the elements of the given array using the ForkJoin framework
+ * @param array the array to sort
+ */
+ public void sort(int[] array) {
+ ForkJoinTask<Void> job = pool.submit(new MergeSortTask(array, 0, array.length));
+ job.join();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/ChatServer.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.StandardSocketOption;
+import java.nio.channels.*;
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implements a chat server, this class holds the list of {@code clients} connected to the server.
+ * It sets up a server socket using AsynchronousServerSocketChannel listening to a specified port.
+ */
+public class ChatServer implements Runnable {
+ private final List<Client> connections = Collections.synchronizedList(new ArrayList<Client>());
+ private int port;
+ private final AsynchronousServerSocketChannel listener;
+ private final AsynchronousChannelGroup channelGroup;
+
+ /**
+ *
+ * @param port to listen to
+ * @throws java.io.IOException when failing to start the server
+ */
+ public ChatServer(int port) throws IOException {
+ channelGroup = AsynchronousChannelGroup.withFixedThreadPool(Runtime.getRuntime().availableProcessors(),
+ Executors.defaultThreadFactory());
+ this.port = port;
+ listener = createListener(channelGroup);
+ }
+
+ /**
+ *
+ * @return The socket address that the server is bound to
+ * @throws java.io.IOException if an I/O error occurs
+ */
+ public SocketAddress getSocketAddress() throws IOException {
+ return listener.getLocalAddress();
+ }
+
+ /**
+ * Start accepting connections
+ */
+ public void run() {
+
+ // call accept to wait for connections, tell it to call our CompletionHandler when there
+ // is a new incoming connection
+ listener.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
+ @Override
+ public void completed(AsynchronousSocketChannel result, Void attachment) {
+ // request a new accept and handle the incoming connection
+ listener.accept(null, this);
+ handleNewConnection(result);
+ }
+
+ @Override
+ public void failed(Throwable exc, Void attachment) {
+ }
+ });
+ }
+
+ /**
+ * Shuts down the server
+ * @throws InterruptedException if terminated while waiting for shutdown
+ * @throws IOException if failing to shutdown the channel group
+ */
+ public void shutdown() throws InterruptedException, IOException {
+ channelGroup.shutdownNow();
+ channelGroup.awaitTermination(1, TimeUnit.SECONDS);
+ }
+
+ /*
+ * Creates a listener and starts accepting connections
+ */
+ private AsynchronousServerSocketChannel createListener(AsynchronousChannelGroup channelGroup) throws IOException {
+ final AsynchronousServerSocketChannel listener = openChannel(channelGroup);
+ listener.setOption(StandardSocketOption.SO_REUSEADDR, true);
+ listener.bind(new InetSocketAddress(port));
+ return listener;
+ }
+
+ private AsynchronousServerSocketChannel openChannel(AsynchronousChannelGroup channelGroup) throws IOException {
+ return AsynchronousServerSocketChannel.open(channelGroup);
+ }
+
+ /**
+ * Creates a new client and adds it to the list of connections.
+ * Sets the clients handler to the initial state of NameReader
+ *
+ * @param channel the newly accepted channel
+ */
+ private void handleNewConnection(AsynchronousSocketChannel channel) {
+ Client client = new Client(channel, new ClientReader(this, new NameReader(this)));
+ try {
+ channel.setOption(StandardSocketOption.TCP_NODELAY, true);
+ } catch (IOException e) {
+ // ignore
+ }
+ connections.add(client);
+ client.run();
+ }
+
+ /**
+ * Sends a message to all clients except the source.
+ * The method is synchronized as it is desired that messages are sent to
+ * all clients in the same order as received.
+ *
+ * @param client the message source
+ * @param message the message to be sent
+ */
+ public void writeMessageToClients(Client client, String message) {
+ synchronized (connections) {
+ for (Client clientConnection : connections) {
+ if (clientConnection != client) {
+ clientConnection.writeMessageFrom(client, message);
+ }
+ }
+ }
+ }
+
+ public void removeClient(Client client) {
+ connections.remove(client);
+ }
+
+ private static void usage() {
+ System.err.println("ChatServer [-port <port number>]");
+ System.exit(1);
+ }
+
+ public static void main(String[] args) throws IOException {
+ int port = 5000;
+ if (args.length != 0 && args.length != 2) {
+ usage();
+ } else if (args.length == 2) {
+ try {
+ if (args[0].equals("-port")) {
+ port = Integer.parseInt(args[1]);
+ } else {
+ usage();
+ }
+ } catch (NumberFormatException e) {
+ usage();
+ }
+ }
+ System.out.println("Running on port " + port);
+ new ChatServer(port).run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/Client.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.CompletionHandler;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Client represents a remote connection to the chat server.
+ * It contains methods for reading and writing messages from the
+ * channel.
+ * Messages are considered to be separated by newline, so incomplete
+ * messages are buffered in the {@code Client}.
+ *
+ * All reads and writes are asynchronous and uses the nio2 asynchronous
+ * elements.
+ */
+class Client {
+ private final AsynchronousSocketChannel channel;
+ private AtomicReference<ClientReader> reader;
+ private String userName;
+ private final StringBuilder messageBuffer = new StringBuilder();
+
+ private final Queue<ByteBuffer> queue = new LinkedList<ByteBuffer>();
+ private boolean writing = false;
+
+ public Client(AsynchronousSocketChannel channel, ClientReader reader) {
+ this.channel = channel;
+ this.reader = new AtomicReference<ClientReader>(reader);
+ }
+
+ /**
+ * Enqueues a write of the buffer to the channel.
+ * The call is asynchronous so the buffer is not safe to modify after
+ * passing the buffer here.
+ *
+ * @param buffer the buffer to send to the channel
+ */
+ private void writeMessage(final ByteBuffer buffer) {
+ boolean threadShouldWrite = false;
+
+ synchronized(queue) {
+ queue.add(buffer);
+ // Currently no thread writing, make this thread dispatch a write
+ if (!writing) {
+ writing = true;
+ threadShouldWrite = true;
+ }
+ }
+
+ if (threadShouldWrite) {
+ writeFromQueue();
+ }
+ }
+
+ private void writeFromQueue() {
+ ByteBuffer buffer;
+
+ synchronized (queue) {
+ buffer = queue.poll();
+ if (buffer == null) {
+ writing = false;
+ }
+ }
+
+ // No new data in buffer to write
+ if (writing) {
+ writeBuffer(buffer);
+ }
+ }
+
+ private void writeBuffer(ByteBuffer buffer) {
+ channel.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
+ @Override
+ public void completed(Integer result, ByteBuffer buffer) {
+ if (buffer.hasRemaining()) {
+ channel.write(buffer, buffer, this);
+ } else {
+ // Go back and check if there is new data to write
+ writeFromQueue();
+ }
+ }
+
+ @Override
+ public void failed(Throwable exc, ByteBuffer attachment) {
+ }
+ });
+ }
+
+ /**
+ * Sends a message
+ * @param string the message
+ */
+ public void writeStringMessage(String string) {
+ writeMessage(ByteBuffer.wrap(string.getBytes()));
+ }
+
+ /**
+ * Send a message from a specific client
+ * @param client the message is sent from
+ * @param message to send
+ */
+ public void writeMessageFrom(Client client, String message) {
+ if (reader.get().acceptsMessages()) {
+ writeStringMessage(client.getUserName() + ": " + message);
+ }
+ }
+
+ /**
+ * Enqueue a read
+ * @param completionHandler callback on completed read
+ */
+ public void read(CompletionHandler<Integer, ? super ByteBuffer> completionHandler) {
+ ByteBuffer input = ByteBuffer.allocate(256);
+ if (!channel.isOpen()) {
+ return;
+ }
+ channel.read(input, input, completionHandler);
+ }
+
+ /**
+ * Closes the channel
+ */
+ public void close() {
+ try {
+ channel.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Run the current states actions.
+ */
+ public void run() {
+ reader.get().run(this);
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public void setReader(ClientReader reader) {
+ this.reader.set(reader);
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void appendMessage(String message) {
+ synchronized (messageBuffer) {
+ messageBuffer.append(message);
+ }
+ }
+
+ /**
+ * @return the next newline separated message in the buffer. null is returned if the buffer
+ * doesn't contain any newline.
+ */
+ public String nextMessage() {
+ synchronized(messageBuffer) {
+ int nextNewline = messageBuffer.indexOf("\n");
+ if (nextNewline == -1) {
+ return null;
+ }
+ String message = messageBuffer.substring(0, nextNewline + 1);
+ messageBuffer.delete(0, nextNewline + 1);
+ return message;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/ClientReader.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.channels.CompletionHandler;
+
+/**
+ * Handles a cycle of reading / writing on the {@code Client}.
+ */
+class ClientReader {
+ private final DataReader callback;
+ private final ChatServer chatServer;
+
+ ClientReader(ChatServer chatServer, DataReader callback) {
+ this.chatServer = chatServer;
+ this.callback = callback;
+ }
+
+ public boolean acceptsMessages() {
+ return callback.acceptsMessages();
+ }
+
+ /**
+ * Runs a cycle of doing a beforeRead action and then enqueing a new
+ * read on the client. Handles closed channels and errors while reading.
+ * If the client is still connected a new round of actions are called.
+ */
+ public void run(final Client client) {
+ callback.beforeRead(client);
+ client.read(new CompletionHandler<Integer, ByteBuffer>() {
+ @Override
+ public void completed(Integer result, ByteBuffer buffer) {
+ // if result is negative or zero the connection has been closed or something gone wrong
+ if (result < 1) {
+ client.close();
+ System.out.println("Closing connection to " + client);
+ chatServer.removeClient(client);
+ } else {
+ callback.onData(client, buffer, result);
+ // enqueue next round of actions
+ client.run();
+ }
+ }
+
+ @Override
+ public void failed(Throwable exc, ByteBuffer buffer) {
+ client.close();
+ chatServer.removeClient(client);
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/DataReader.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.ByteBuffer;
+
+public interface DataReader {
+ void beforeRead(Client client);
+ void onData(Client client, ByteBuffer buffer, int bytes);
+ boolean acceptsMessages();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/MessageReader.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.ByteBuffer;
+
+/**
+ * Writes all messages in our buffer to the other clients
+ * and appends new data read from the socket to our buffer
+ */
+class MessageReader implements DataReader {
+ private final ChatServer chatServer;
+
+ public MessageReader(ChatServer chatServer) {
+ this.chatServer = chatServer;
+ }
+
+ public boolean acceptsMessages() {
+ return true;
+ }
+
+ /**
+ * Write all full messages in our buffer to
+ * the other clients
+ *
+ * @param client the client to read messages from
+ */
+ @Override
+ public void beforeRead(Client client) {
+ // Check if we have any messages buffered and send them
+ String message = client.nextMessage();
+ while (message != null) {
+ chatServer.writeMessageToClients(client, message);
+ message = client.nextMessage();
+ }
+ }
+
+ /**
+ * Append the read buffer to the clients message buffer
+ * @param client the client to append messages to
+ * @param buffer the buffer we received from the socket
+ * @param bytes the number of bytes read into the buffer
+ */
+ @Override
+ public void onData(Client client, ByteBuffer buffer, int bytes) {
+ buffer.flip();
+ // Just append the message on the buffer
+ client.appendMessage(new String(buffer.array(), 0, bytes));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/NameReader.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.nio.ByteBuffer;
+
+/**
+ * The first state a newly connected {@code Client} is in, this
+ * handles writing out the welcoming message and reads the response
+ * up to a newline. When a newline character have been received
+ * it changes the handler from NameReader to MessageReader on the
+ * client.
+ */
+class NameReader implements DataReader {
+ private final StringBuilder buffer = new StringBuilder();
+ private final ChatServer chatServer;
+ private boolean once = true;
+ private static final String NEWLINE = "\n";
+
+ public NameReader(ChatServer chatServer) {
+ this.chatServer = chatServer;
+ }
+
+ /**
+ * Writes the welcoming message to the client the first time this method
+ * is called.
+ *
+ * @param client the client to receive the message
+ */
+ @Override
+ public void beforeRead(Client client) {
+ // if it is a long name that takes more than one read we only want to display Name: once.
+ if (once) {
+ client.writeStringMessage("Name: ");
+ once = false;
+ }
+ }
+
+ public boolean acceptsMessages() {
+ return false;
+ }
+
+ /**
+ * Receives incoming data from the socket, searches for a newline
+ * and tries to set the username if one is found
+ */
+ @Override
+ public void onData(Client client, ByteBuffer buffer, int bytes) {
+ buffer.flip();
+ String name;
+ name = this.buffer.append(new String(buffer.array(), 0, bytes)).toString();
+ if (name.contains(NEWLINE)) {
+ onUserNameRead(client, name);
+ }
+ }
+
+ /**
+ * Splits the name on the newlines, takes the first as the username
+ * and appends everything else to the clients message buffer.
+ * Sets the clients handler to MessageReader.
+ *
+ * @param client the client to set the username for
+ * @param name the string containing the buffered input
+ */
+ private void onUserNameRead(Client client, String name) {
+ String[] strings = name.split(NEWLINE, 2);
+ client.setUserName(strings[0].trim());
+ sendRemainingParts(client, strings);
+ client.setReader(new ClientReader(chatServer, new MessageReader(chatServer)));
+ client.writeStringMessage("Welcome " + client.getUserName() + "\n");
+ }
+
+ /**
+ * Appends the remaining parts to the clients message buffer
+ *
+ * @param client the client
+ * @param strings the messages to append to the buffer
+ */
+ private void sendRemainingParts(Client client, String[] strings) {
+ for (int i = 1; i < strings.length; ++i) {
+ client.appendMessage(strings[i]);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/sample/nio/chatserver/README.txt Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,62 @@
+A Simple Chat Server Example
+
+INTRODUCTION
+============
+This directory contains a very simple chat server, the server takes input from a
+socket ("user") and sends it to all other connected sockets ("users") along with
+the provided name the user was asked for when first connecting.
+
+The server was written to demonstrate the asynchronous I/O API in JDK 7.
+The sample assumes the reader has some familiarity with the subject matter.
+
+SETUP
+=====
+
+The server must be built with version 7 (or later) of the JDK.
+The server is built with:
+
+ % mkdir build
+ % javac -source 7 -target 7 -d build *.java
+
+EXECUTION
+=========
+
+ % java -classpath build ChatServer [-port <port number>]
+
+ Usage: ChatServer [options]
+ options:
+ -port port port number
+ default: 5000
+
+CLIENT EXECUTION
+================
+
+No client binary is included in the sample.
+Connections can be made using for example the telnet command or any program
+that supports a raw TCP connection to a port.
+
+SOURCE CODE OVERVIEW
+====================
+ChatServer is the main class, it handles the startup and handles incoming
+connections on the listening sockets. It keeps a list of connected client
+and provides methods for sending a message to them.
+
+Client represents a connected user, it provides methods for reading/writing
+from/to the underlying socket. It also contains a buffer of input read from
+the user.
+
+DataReader provides the interface of the two states a user can
+be in. Waiting for a name (and not receiving any messages while doing so, implemented
+by NameReader) and waiting for messages from the user (implemented by MessageReader).
+
+ClientReader contains the "main loop" for a connected client.
+
+NameReader is the initial state for a new client, it sends the user a string and
+waits for a response before changing the state to MessageReader.
+
+MessageReader is the main state for a client, it checks for new messages to send to
+other clients and reads messages from the client.
+
+FINALLY
+=======
+This is a sample: it is not production quality and isn't optimized for performance.
--- a/jdk/src/solaris/bin/java_md.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/bin/java_md.c Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,10 @@
#define JVM_DLL "libjvm.so"
#define JAVA_DLL "libjava.so"
+/* help jettison the LD_LIBRARY_PATH settings in the future */
+#ifndef SETENV_REQUIRED
+#define SETENV_REQUIRED
+#endif
/*
* If a processor / os combination has the ability to run binaries of
* two data models and cohabitation of jre/jdk bits with both data
@@ -106,10 +110,22 @@
* Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
* desired data model path, regardless if data models matched or not. The
* launcher subsequently exec'ed the desired executable, in order to make the
- * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
- * case, the launcher dlopens the target libjvm.so. All other required
- * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
- * baked into the shared libraries, by the build infrastructure at compile time.
+ * LD_LIBRARY_PATH path available, for the runtime linker.
+ *
+ * Now, in most cases,the launcher will dlopen the target libjvm.so. All
+ * required libraries are loaded by the runtime linker, using the
+ * $RPATH/$ORIGIN baked into the shared libraries at compile time. Therefore,
+ * in most cases, the launcher will only exec, if the data models are
+ * mismatched, and will not set any environment variables, regardless of the
+ * data models.
+ *
+ * However, if the environment contains a LD_LIBRARY_PATH, this will cause the
+ * launcher to inspect the LD_LIBRARY_PATH. The launcher will check
+ * a. if the LD_LIBRARY_PATH's first component is the the path to the desired
+ * libjvm.so
+ * b. if any other libjvm.so is found in any of the paths.
+ * If case b is true, then the launcher will set the LD_LIBRARY_PATH to the
+ * desired JRE and reexec, in order to propagate the environment.
*
* Main
* (incoming argv)
@@ -137,11 +153,11 @@
* | |
* | |
* \|/ \|/
- * YES (find the desired executable and exec child)
+ * YES Find the desired executable/library
* | |
* | |
* \|/ \|/
- * CheckJvmType Main
+ * CheckJvmType RequiresSetenv
* (removes -client, -server, etc.)
* |
* |
@@ -156,7 +172,42 @@
* processes version options,
* creates argument list for vm,
* etc.)
- *
+ * |
+ * |
+ * \|/
+ * RequiresSetenv
+ * Is LD_LIBRARY_PATH
+ * and friends set ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ * YES YES --> Continue
+ * |
+ * |
+ * \|/
+ * Path is desired JRE ? YES --> Have Desired Model ? NO --> Re-exec --> Main
+ * NO YES --> Continue
+ * |
+ * |
+ * \|/
+ * Paths have well known
+ * jvm paths ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ * YES YES --> Continue
+ * |
+ * |
+ * \|/
+ * Does libjvm.so exit
+ * in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
+ * YES YES --> Continue
+ * |
+ * |
+ * \|/
+ * Set the LD_LIBRARY_PATH
+ * |
+ * |
+ * \|/
+ * Re-exec
+ * |
+ * |
+ * \|/
+ * Main
*/
static const char * SetExecname(char **argv);
@@ -182,6 +233,130 @@
}
}
+#ifdef SETENV_REQUIRED
+static jboolean
+JvmExists(const char *path) {
+ char tmp[PATH_MAX + 1];
+ struct stat statbuf;
+ JLI_Snprintf(tmp, PATH_MAX, "%s/%s", path, JVM_DLL);
+ if (stat(tmp, &statbuf) == 0) {
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+/*
+ * contains a lib/$LIBARCH/{server,client}/libjvm.so ?
+ */
+static jboolean
+ContainsLibJVM(int wanted, const char *env) {
+ char clientPattern[PATH_MAX + 1];
+ char serverPattern[PATH_MAX + 1];
+ char *envpath;
+ char *path;
+ jboolean clientPatternFound;
+ jboolean serverPatternFound;
+
+ /* fastest path */
+ if (env == NULL) {
+ return JNI_FALSE;
+ }
+
+ /* the usual suspects */
+ JLI_Snprintf(clientPattern, PATH_MAX, "lib/%s/client", GetArchPath(wanted));
+ JLI_Snprintf(serverPattern, PATH_MAX, "lib/%s/server", GetArchPath(wanted));
+
+ /* to optimize for time, test if any of our usual suspects are present. */
+ clientPatternFound = JLI_StrStr(env, clientPattern) != NULL;
+ serverPatternFound = JLI_StrStr(env, serverPattern) != NULL;
+ if (clientPatternFound == JNI_FALSE && serverPatternFound == JNI_FALSE) {
+ return JNI_FALSE;
+ }
+
+ /*
+ * we have a suspicious path component, check if it contains a libjvm.so
+ */
+ envpath = JLI_StringDup(env);
+ for (path = JLI_StrTok(envpath, ":"); path != NULL; path = JLI_StrTok(NULL, ":")) {
+ if (clientPatternFound && JLI_StrStr(path, clientPattern) != NULL) {
+ if (JvmExists(path)) {
+ JLI_MemFree(envpath);
+ return JNI_TRUE;
+ }
+ }
+ if (serverPatternFound && JLI_StrStr(path, serverPattern) != NULL) {
+ if (JvmExists(path)) {
+ JLI_MemFree(envpath);
+ return JNI_TRUE;
+ }
+ }
+ }
+ JLI_MemFree(envpath);
+ return JNI_FALSE;
+}
+
+/*
+ * Test whether the environment variable needs to be set, see flowchart.
+ */
+static jboolean
+RequiresSetenv(int wanted, const char *jvmpath) {
+ char jpath[PATH_MAX + 1];
+ char *llp;
+ char *dmllp = NULL;
+ char *p; /* a utility pointer */
+
+ llp = getenv("LD_LIBRARY_PATH");
+#ifdef __solaris__
+ dmllp = (CURRENT_DATA_MODEL == 32)
+ ? getenv("LD_LIBRARY_PATH_32")
+ : getenv("LD_LIBRARY_PATH_64");
+#endif /* __solaris__ */
+ /* no environment variable is a good environment variable */
+ if (llp == NULL && dmllp == NULL) {
+ return JNI_FALSE;
+ }
+#ifdef __linux
+ /*
+ * On linux, if a binary is running as sgid or suid, glibc sets
+ * LD_LIBRARY_PATH to the empty string for security purposes. (In contrast,
+ * on Solaris the LD_LIBRARY_PATH variable for a privileged binary does not
+ * lose its settings; but the dynamic linker does apply more scrutiny to the
+ * path.) The launcher uses the value of LD_LIBRARY_PATH to prevent an exec
+ * loop, here and further downstream. Therefore, if we are running sgid or
+ * suid, this function's setting of LD_LIBRARY_PATH will be ineffective and
+ * we should case a return from the calling function. Getting the right
+ * libraries will be handled by the RPATH. In reality, this check is
+ * redundant, as the previous check for a non-null LD_LIBRARY_PATH will
+ * return back to the calling function forthwith, it is left here to safe
+ * guard against any changes, in the glibc's existing security policy.
+ */
+ if ((getgid() != getegid()) || (getuid() != geteuid())) {
+ return JNI_FALSE;
+ }
+#endif /* __linux */
+
+ /*
+ * Prevent recursions. Since LD_LIBRARY_PATH is the one which will be set by
+ * previous versions of the JRE, thus it is the only path that matters here.
+ * So we check to see if the desired JRE is set.
+ */
+ JLI_StrNCpy(jpath, jvmpath, PATH_MAX);
+ p = JLI_StrRChr(jpath, '/');
+ *p = '\0';
+ if (llp != NULL && JLI_StrNCmp(llp, jpath, JLI_StrLen(jpath)) == 0) {
+ return JNI_FALSE;
+ }
+
+ /* scrutinize all the paths further */
+ if (llp != NULL && ContainsLibJVM(wanted, llp)) {
+ return JNI_TRUE;
+ }
+ if (dmllp != NULL && ContainsLibJVM(wanted, dmllp)) {
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+#endif /* SETENV_REQUIRED */
+
void
CreateExecutionEnvironment(int *pargc, char ***pargv,
char jrepath[], jint so_jrepath,
@@ -195,7 +370,6 @@
* informative to issue an error message based on whether or not the
* os/processor combination has dual mode capabilities.
*/
-
jboolean jvmpathExists;
/* Compute/set the name of the executable */
@@ -207,13 +381,24 @@
char * jvmtype = NULL;
int argc = *pargc;
char **argv = *pargv;
-
int running = CURRENT_DATA_MODEL;
int wanted = running; /* What data mode is being
asked for? Current model is
fine unless another model
is asked for */
+#ifdef SETENV_REQUIRED
+ jboolean mustsetenv = JNI_FALSE;
+ char *runpath = NULL; /* existing effective LD_LIBRARY_PATH setting */
+ char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
+ char* newpath = NULL; /* path on new LD_LIBRARY_PATH */
+ char* lastslash = NULL;
+ char** newenvp = NULL; /* current environment */
+#ifdef __solaris__
+ char* dmpath = NULL; /* data model specific LD_LIBRARY_PATH,
+ Solaris only */
+#endif /* __solaris__ */
+#endif /* SETENV_REQUIRED */
char** newargv = NULL;
int newargc = 0;
@@ -300,9 +485,18 @@
}
/*
* we seem to have everything we need, so without further ado
- * we return back.
+ * we return back, otherwise proceed to set the environment.
*/
+#ifdef SETENV_REQUIRED
+ mustsetenv = RequiresSetenv(wanted, jvmpath);
+ JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE");
+
+ if (mustsetenv == JNI_FALSE) {
+ return;
+ }
+#else
return;
+#endif /* SETENV_REQUIRED */
} else { /* do the same speculatively or exit */
#ifdef DUAL_MODE
if (running != wanted) {
@@ -331,67 +525,240 @@
/* exec child can do error checking on the existence of the path */
jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted));
-
+#ifdef SETENV_REQUIRED
+ mustsetenv = RequiresSetenv(wanted, jvmpath);
+#endif /* SETENV_REQUIRED */
}
#else
JLI_ReportErrorMessage(JRE_ERROR2, wanted);
exit(1);
#endif
- }
+ }
+#ifdef SETENV_REQUIRED
+ if (mustsetenv) {
+ /*
+ * We will set the LD_LIBRARY_PATH as follows:
+ *
+ * o $JVMPATH (directory portion only)
+ * o $JRE/lib/$LIBARCHNAME
+ * o $JRE/../lib/$LIBARCHNAME
+ *
+ * followed by the user's previous effective LD_LIBRARY_PATH, if
+ * any.
+ */
+
+#ifdef __solaris__
+ /*
+ * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
+ * variables:
+ *
+ * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
+ * data-model specific variables are not set.
+ *
+ * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
+ * for 64-bit binaries.
+ *
+ * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
+ * for 32-bit binaries.
+ *
+ * The vm uses LD_LIBRARY_PATH to set the java.library.path system
+ * property. To shield the vm from the complication of multiple
+ * LD_LIBRARY_PATH variables, if the appropriate data model
+ * specific variable is set, we will act as if LD_LIBRARY_PATH had
+ * the value of the data model specific variant and the data model
+ * specific variant will be unset. Note that the variable for the
+ * *wanted* data model must be used (if it is set), not simply the
+ * current running data model.
+ */
+
+ switch (wanted) {
+ case 0:
+ if (running == 32) {
+ dmpath = getenv("LD_LIBRARY_PATH_32");
+ wanted = 32;
+ } else {
+ dmpath = getenv("LD_LIBRARY_PATH_64");
+ wanted = 64;
+ }
+ break;
- {
- char *newexec = execname;
+ case 32:
+ dmpath = getenv("LD_LIBRARY_PATH_32");
+ break;
+
+ case 64:
+ dmpath = getenv("LD_LIBRARY_PATH_64");
+ break;
+
+ default:
+ JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
+ exit(1); /* unknown value in wanted */
+ break;
+ }
+
+ /*
+ * If dmpath is NULL, the relevant data model specific variable is
+ * not set and normal LD_LIBRARY_PATH should be used.
+ */
+ if (dmpath == NULL) {
+ runpath = getenv("LD_LIBRARY_PATH");
+ } else {
+ runpath = dmpath;
+ }
+#else
+ /*
+ * If not on Solaris, assume only a single LD_LIBRARY_PATH
+ * variable.
+ */
+ runpath = getenv("LD_LIBRARY_PATH");
+#endif /* __solaris__ */
+
+ /* runpath contains current effective LD_LIBRARY_PATH setting */
+
+ jvmpath = JLI_StringDup(jvmpath);
+ new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
+ 2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
+ JLI_StrLen(jvmpath) + 52);
+ newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
+
+
+ /*
+ * Create desired LD_LIBRARY_PATH value for target data model.
+ */
+ {
+ /* remove the name of the .so from the JVM path */
+ lastslash = JLI_StrRChr(jvmpath, '/');
+ if (lastslash)
+ *lastslash = '\0';
+
+ sprintf(new_runpath, "LD_LIBRARY_PATH="
+ "%s:"
+ "%s/lib/%s:"
+ "%s/../lib/%s",
+ jvmpath,
#ifdef DUAL_MODE
- /*
- * If the data model is being changed, the path to the
- * executable must be updated accordingly; the executable name
- * and directory the executable resides in are separate. In the
- * case of 32 => 64, the new bits are assumed to reside in, e.g.
- * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
- * the bits are assumed to be in "olddir/../execname". For example,
- *
- * olddir/sparcv9/execname
- * olddir/amd64/execname
- *
- * for Solaris SPARC and Linux amd64, respectively.
- */
-
- if (running != wanted) {
- char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
- char *olddir = oldexec;
- char *oldbase = JLI_StrRChr(oldexec, '/');
+ jrepath, GetArchPath(wanted),
+ jrepath, GetArchPath(wanted)
+#else
+ jrepath, arch,
+ jrepath, arch
+#endif
+ );
- newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
- *oldbase++ = 0;
- sprintf(newexec, "%s/%s/%s", olddir,
- ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
- argv[0] = newexec;
+ /*
+ * Check to make sure that the prefix of the current path is the
+ * desired environment variable setting, though the RequiresSetenv
+ * checks if the desired runpath exists, this logic does a more
+ * comprehensive check.
+ */
+ if (runpath != NULL &&
+ JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 &&
+ (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
+ (running == wanted) /* data model does not have to be changed */
+#ifdef __solaris__
+ && (dmpath == NULL) /* data model specific variables not set */
+#endif
+ ) {
+
+ return;
+
+ }
+ }
+
+ /*
+ * Place the desired environment setting onto the prefix of
+ * LD_LIBRARY_PATH. Note that this prevents any possible infinite
+ * loop of execv() because we test for the prefix, above.
+ */
+ if (runpath != 0) {
+ JLI_StrCat(new_runpath, ":");
+ JLI_StrCat(new_runpath, runpath);
+ }
+
+ if (putenv(new_runpath) != 0) {
+ exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
+ properly */
+ }
+
+ /*
+ * Unix systems document that they look at LD_LIBRARY_PATH only
+ * once at startup, so we have to re-exec the current executable
+ * to get the changed environment variable to have an effect.
+ */
+
+#ifdef __solaris__
+ /*
+ * If dmpath is not NULL, remove the data model specific string
+ * in the environment for the exec'ed child.
+ */
+ if (dmpath != NULL)
+ (void)UnsetEnv((wanted == 32) ? "LD_LIBRARY_PATH_32" : "LD_LIBRARY_PATH_64");
+#endif
+
+ newenvp = environ;
}
-#endif
- JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
- (void)fflush(stdout);
- (void)fflush(stderr);
- execv(newexec, argv);
- JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
+#endif /* SETENV_REQUIRED */
+ {
+ char *newexec = execname;
+#ifdef DUAL_MODE
+ /*
+ * If the data model is being changed, the path to the
+ * executable must be updated accordingly; the executable name
+ * and directory the executable resides in are separate. In the
+ * case of 32 => 64, the new bits are assumed to reside in, e.g.
+ * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
+ * the bits are assumed to be in "olddir/../execname". For example,
+ *
+ * olddir/sparcv9/execname
+ * olddir/amd64/execname
+ *
+ * for Solaris SPARC and Linux amd64, respectively.
+ */
+
+ if (running != wanted) {
+ char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
+ char *olddir = oldexec;
+ char *oldbase = JLI_StrRChr(oldexec, '/');
+
+
+ newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
+ *oldbase++ = 0;
+ sprintf(newexec, "%s/%s/%s", olddir,
+ ((wanted == 64) ? LIBARCH64NAME : ".."), oldbase);
+ argv[0] = newexec;
+ }
+#endif /* DUAL_MODE */
+ JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+#ifdef SETENV_REQUIRED
+ if (mustsetenv) {
+ execve(newexec, argv, newenvp);
+ } else {
+ execv(newexec, argv);
+ }
+#else
+ execv(newexec, argv);
+#endif /* SETENV_REQUIRED */
+ JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
#ifdef DUAL_MODE
- if (running != wanted) {
- JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
-# ifdef __solaris__
-# ifdef __sparc
- JLI_ReportErrorMessage(JRE_ERROR6);
-# else
- JLI_ReportErrorMessage(JRE_ERROR7);
-# endif
+ if (running != wanted) {
+ JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
+#ifdef __solaris__
+#ifdef __sparc
+ JLI_ReportErrorMessage(JRE_ERROR6);
+#else
+ JLI_ReportErrorMessage(JRE_ERROR7);
+#endif /* __sparc */
+ }
+#endif /* __solaris__ */
+#endif /* DUAL_MODE */
+
}
-# endif
-#endif
-
- }
- exit(1);
+ exit(1);
}
-
}
/*
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Tue Apr 12 14:23:03 2011 -0700
@@ -56,11 +56,11 @@
{
if (type == DosFileAttributeView.class) {
return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
if (type == UserDefinedFileAttributeView.class) {
return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
return super.getFileAttributeView(obj, type, options);
}
@@ -72,11 +72,11 @@
{
if (name.equals("dos")) {
return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
if (name.equals("user")) {
return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
return super.getFileAttributeView(obj, name, options);
}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Tue Apr 12 14:23:03 2011 -0700
@@ -57,11 +57,11 @@
{
if (type == AclFileAttributeView.class) {
return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
if (type == UserDefinedFileAttributeView.class) {
return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
}
return super.getFileAttributeView(obj, type, options);
}
@@ -73,10 +73,10 @@
{
if (name.equals("acl"))
return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
if (name.equals("user"))
return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
- followLinks(options));
+ Util.followLinks(options));
return super.getFileAttributeView(obj, name, options);
}
}
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Tue Apr 12 14:23:03 2011 -0700
@@ -105,20 +105,6 @@
return (UnixPath)obj;
}
- boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
-
@Override
@SuppressWarnings("unchecked")
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
@@ -126,7 +112,7 @@
LinkOption... options)
{
UnixPath file = UnixPath.toUnixPath(obj);
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
if (type == BasicFileAttributeView.class)
return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
if (type == PosixFileAttributeView.class)
@@ -163,7 +149,7 @@
LinkOption... options)
{
UnixPath file = UnixPath.toUnixPath(obj);
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
if (name.equals("basic"))
return UnixFileAttributeViews.createBasicView(file, followLinks);
if (name.equals("posix"))
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Tue Apr 12 14:23:03 2011 -0700
@@ -819,13 +819,13 @@
}
@Override
- public Path toRealPath(boolean resolveLinks) throws IOException {
+ public Path toRealPath(LinkOption... options) throws IOException {
checkRead();
UnixPath absolute = toAbsolutePath();
- // if resolveLinks is true then use realpath
- if (resolveLinks) {
+ // if resolving links then use realpath
+ if (Util.followLinks(options)) {
try {
byte[] rp = realpath(absolute);
return new UnixPath(getFileSystem(), rp);
@@ -834,7 +834,7 @@
}
}
- // if resolveLinks is false then eliminate "." and also ".."
+ // if not resolving links then eliminate "." and also ".."
// where the previous element is not a link.
UnixPath result = fs.rootDirectory();
for (int i=0; i<absolute.getNameCount(); i++) {
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixSecureDirectoryStream.java Tue Apr 12 14:23:03 2011 -0700
@@ -81,20 +81,6 @@
return (UnixPath)obj;
}
- private boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
-
/**
* Opens sub-directory in this directory
*/
@@ -105,7 +91,7 @@
{
UnixPath file = getName(obj);
UnixPath child = ds.directory().resolve(file);
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
// permission check using name resolved against original path of directory
SecurityManager sm = System.getSecurityManager();
@@ -316,7 +302,7 @@
LinkOption... options)
{
UnixPath file = getName(obj);
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
return getFileAttributeViewImpl(file, type, followLinks);
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystem.java Tue Apr 12 14:23:03 2011 -0700
@@ -56,8 +56,9 @@
// parse default directory and check it is absolute
WindowsPathParser.Result result = WindowsPathParser.parse(dir);
- if (result.type() != WindowsPathType.ABSOLUTE)
- throw new AssertionError("Default directory must be absolute/non-UNC");
+ if ((result.type() != WindowsPathType.ABSOLUTE) &&
+ (result.type() != WindowsPathType.UNC))
+ throw new AssertionError("Default directory is not an absolute path");
this.defaultDirectory = result.path();
this.defaultRoot = result.root();
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Tue Apr 12 14:23:03 2011 -0700
@@ -150,20 +150,6 @@
}
}
- private boolean followLinks(LinkOption... options) {
- boolean followLinks = true;
- for (LinkOption option: options) {
- if (option == LinkOption.NOFOLLOW_LINKS) {
- followLinks = false;
- continue;
- }
- if (option == null)
- throw new NullPointerException();
- throw new AssertionError("Should not get here");
- }
- return followLinks;
- }
-
@Override
@SuppressWarnings("unchecked")
public <V extends FileAttributeView> V
@@ -172,7 +158,7 @@
WindowsPath file = WindowsPath.toWindowsPath(obj);
if (view == null)
throw new NullPointerException();
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
if (view == BasicFileAttributeView.class)
return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
if (view == DosFileAttributeView.class)
@@ -209,7 +195,7 @@
@Override
public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
WindowsPath file = WindowsPath.toWindowsPath(obj);
- boolean followLinks = followLinks(options);
+ boolean followLinks = Util.followLinks(options);
if (name.equals("basic"))
return WindowsFileAttributeViews.createBasicView(file, followLinks);
if (name.equals("dos"))
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Tue Apr 12 14:23:03 2011 -0700
@@ -831,9 +831,9 @@
}
@Override
- public WindowsPath toRealPath(boolean resolveLinks) throws IOException {
+ public WindowsPath toRealPath(LinkOption... options) throws IOException {
checkRead();
- String rp = WindowsLinkSupport.getRealPath(this, resolveLinks);
+ String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options));
return createFromNormalizedPath(getFileSystem(), rp);
}
--- a/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/com/sun/management/OperatingSystem_md.c Tue Apr 12 14:23:03 2011 -0700
@@ -30,6 +30,7 @@
#include "management.h"
#include "com_sun_management_OperatingSystem.h"
+#include <psapi.h>
#include <errno.h>
#include <stdlib.h>
@@ -53,41 +54,12 @@
return result;
}
-// From psapi.h
-typedef struct _PROCESS_MEMORY_COUNTERS {
- DWORD cb;
- DWORD PageFaultCount;
- SIZE_T PeakWorkingSetSize;
- SIZE_T WorkingSetSize;
- SIZE_T QuotaPeakPagedPoolUsage;
- SIZE_T QuotaPagedPoolUsage;
- SIZE_T QuotaPeakNonPagedPoolUsage;
- SIZE_T QuotaNonPagedPoolUsage;
- SIZE_T PagefileUsage;
- SIZE_T PeakPagefileUsage;
-} PROCESS_MEMORY_COUNTERS;
-
-static HINSTANCE hInstPsapi = NULL;
-typedef BOOL (WINAPI *LPFNGETPROCESSMEMORYINFO)(HANDLE, PROCESS_MEMORY_COUNTERS*, DWORD);
-
-static jboolean is_nt = JNI_FALSE;
static HANDLE main_process;
JNIEXPORT void JNICALL
Java_com_sun_management_OperatingSystem_initialize
(JNIEnv *env, jclass cls)
{
- OSVERSIONINFO oi;
- oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&oi);
- switch(oi.dwPlatformId) {
- case VER_PLATFORM_WIN32_WINDOWS: is_nt = JNI_FALSE; break;
- case VER_PLATFORM_WIN32_NT: is_nt = JNI_TRUE; break;
- default:
- throw_internal_error(env, "Unsupported Platform");
- return;
- }
-
main_process = GetCurrentProcess();
}
@@ -95,31 +67,12 @@
Java_com_sun_management_OperatingSystem_getCommittedVirtualMemorySize0
(JNIEnv *env, jobject mbean)
{
-
- /*
- * In bytes. NT/2000/XP only - using GetProcessMemoryInfo from psapi.dll
- */
- static LPFNGETPROCESSMEMORYINFO lpfnGetProcessMemoryInfo = NULL;
- static volatile jboolean psapi_inited = JNI_FALSE;
PROCESS_MEMORY_COUNTERS pmc;
-
- if (!is_nt) return -1;
-
- if (!psapi_inited) {
- psapi_inited = JNI_TRUE;
- if ((hInstPsapi = LoadLibrary("PSAPI.DLL")) == NULL) return -1;
- if ((lpfnGetProcessMemoryInfo = (LPFNGETPROCESSMEMORYINFO)
- GetProcAddress( hInstPsapi, "GetProcessMemoryInfo")) == NULL) {
- FreeLibrary(hInstPsapi);
- return -1;
- }
+ if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
+ return (jlong)-1L;
+ } else {
+ return (jlong) pmc.PagefileUsage;
}
-
- if (lpfnGetProcessMemoryInfo == NULL) return -1;
-
- lpfnGetProcessMemoryInfo(main_process, &pmc,
- sizeof(PROCESS_MEMORY_COUNTERS));
- return (jlong) pmc.PagefileUsage;
}
JNIEXPORT jlong JNICALL
@@ -148,20 +101,15 @@
FILETIME process_creation_time, process_exit_time,
process_user_time, process_kernel_time;
- // Windows NT only
- if (is_nt) {
- // Using static variables declared above
- // Units are 100-ns intervals. Convert to ns.
- GetProcessTimes(main_process, &process_creation_time,
- &process_exit_time,
- &process_kernel_time, &process_user_time);
- return (jlong_from(process_user_time.dwHighDateTime,
- process_user_time.dwLowDateTime) +
- jlong_from(process_kernel_time.dwHighDateTime,
- process_kernel_time.dwLowDateTime)) * 100;
- } else {
- return -1;
- }
+ // Using static variables declared above
+ // Units are 100-ns intervals. Convert to ns.
+ GetProcessTimes(main_process, &process_creation_time,
+ &process_exit_time,
+ &process_kernel_time, &process_user_time);
+ return (jlong_from(process_user_time.dwHighDateTime,
+ process_user_time.dwLowDateTime) +
+ jlong_from(process_kernel_time.dwHighDateTime,
+ process_kernel_time.dwLowDateTime)) * 100;
}
JNIEXPORT jlong JNICALL
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Tue Apr 12 14:23:03 2011 -0700
@@ -23,9 +23,9 @@
* questions.
*/
-/* Access APIs for Win2K and above */
+/* Access APIs for WinXP and above */
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
#endif
#include <assert.h>
@@ -60,13 +60,17 @@
JNIEXPORT void JNICALL
Java_java_io_WinNTFileSystem_initIDs(JNIEnv *env, jclass cls)
{
- HANDLE handle;
+ HMODULE handle;
jclass fileClass = (*env)->FindClass(env, "java/io/File");
if (!fileClass) return;
ids.path =
(*env)->GetFieldID(env, fileClass, "path", "Ljava/lang/String;");
- handle = LoadLibrary("kernel32");
- if (handle != NULL) {
+
+ // GetFinalPathNameByHandle requires Windows Vista or newer
+ if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
+ (LPCWSTR)&CreateFileW, &handle) != 0)
+ {
GetFinalPathNameByHandle_func = (GetFinalPathNameByHandleProc)
GetProcAddress(handle, "GetFinalPathNameByHandleW");
}
@@ -824,8 +828,6 @@
return ret;
}
-typedef BOOL (WINAPI* GetVolumePathNameProc) (LPCWSTR, LPWSTR, DWORD);
-
JNIEXPORT jlong JNICALL
Java_java_io_WinNTFileSystem_getSpace0(JNIEnv *env, jobject this,
jobject file, jint t)
@@ -834,14 +836,7 @@
jlong rv = 0L;
WCHAR *pathbuf = fileToNTPath(env, file, ids.path);
- HMODULE h = LoadLibrary("kernel32");
- GetVolumePathNameProc getVolumePathNameW = NULL;
- if (h) {
- getVolumePathNameW
- = (GetVolumePathNameProc)GetProcAddress(h, "GetVolumePathNameW");
- }
-
- if (getVolumePathNameW(pathbuf, volname, MAX_PATH_LENGTH)) {
+ if (GetVolumePathNameW(pathbuf, volname, MAX_PATH_LENGTH)) {
ULARGE_INTEGER totalSpace, freeSpace, usableSpace;
if (GetDiskFreeSpaceExW(volname, &usableSpace, &totalSpace, &freeSpace)) {
switch(t) {
@@ -860,9 +855,6 @@
}
}
- if (h) {
- FreeLibrary(h);
- }
free(pathbuf);
return rv;
}
--- a/jdk/src/windows/native/java/lang/java_props_md.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/java/lang/java_props_md.c Tue Apr 12 14:23:03 2011 -0700
@@ -196,42 +196,23 @@
/*
* Code to figure out the user's home directory using shell32.dll
*/
-typedef HRESULT (WINAPI *GetSpecialFolderType)(HWND, int, LPITEMIDLIST *);
-typedef BOOL (WINAPI *GetPathFromIDListType)(LPCITEMIDLIST, LPSTR);
-
WCHAR*
getHomeFromShell32()
{
- HMODULE lib = LoadLibraryW(L"SHELL32.DLL");
- GetSpecialFolderType do_get_folder;
- GetPathFromIDListType do_get_path;
HRESULT rc;
LPITEMIDLIST item_list = 0;
WCHAR *p;
WCHAR path[MAX_PATH+1];
int size = MAX_PATH+1;
- if (lib == 0) {
- // We can't load the library !!??
- return NULL;
- }
-
- do_get_folder = (GetSpecialFolderType)GetProcAddress(lib, "SHGetSpecialFolderLocation");
- do_get_path = (GetPathFromIDListType)GetProcAddress(lib, "SHGetPathFromIDListW");
-
- if (do_get_folder == 0 || do_get_path == 0) {
- // the library doesn't hold the right functions !!??
- return NULL;
- }
-
- rc = (*do_get_folder)(NULL, CSIDL_DESKTOPDIRECTORY, &item_list);
+ rc = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &item_list);
if (!SUCCEEDED(rc)) {
// we can't find the shell folder.
return NULL;
}
path[0] = 0;
- (*do_get_path)(item_list, (LPSTR)path);
+ SHGetPathFromIDListW(item_list, (LPWSTR)path);
/* Get the parent of Desktop directory */
p = wcsrchr(path, L'\\');
@@ -253,17 +234,7 @@
static boolean
haveMMX(void)
{
- boolean mmx = 0;
- HMODULE lib = LoadLibrary("KERNEL32");
- if (lib != NULL) {
- BOOL (WINAPI *isProcessorFeaturePresent)(DWORD) =
- (BOOL (WINAPI *)(DWORD))
- GetProcAddress(lib, "IsProcessorFeaturePresent");
- if (isProcessorFeaturePresent != NULL)
- mmx = isProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE);
- FreeLibrary(lib);
- }
- return mmx;
+ return IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE);
}
static const char *
@@ -532,10 +503,19 @@
if (uname != NULL && wcslen(uname) > 0) {
sprops.user_name = _wcsdup(uname);
} else {
- WCHAR buf[100];
- int buflen = sizeof(buf);
- sprops.user_name =
- GetUserNameW(buf, &buflen) ? _wcsdup(buf) : L"unknown";
+ DWORD buflen = 0;
+ if (GetUserNameW(NULL, &buflen) == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ uname = (WCHAR*)malloc(buflen * sizeof(WCHAR));
+ if (uname != NULL && GetUserNameW(uname, &buflen) == 0) {
+ free(uname);
+ uname = NULL;
+ }
+ } else {
+ uname = NULL;
+ }
+ sprops.user_name = (uname != NULL) ? uname : L"unknown";
}
}
@@ -633,8 +613,8 @@
/* Current directory */
{
WCHAR buf[MAX_PATH];
- GetCurrentDirectoryW(sizeof(buf), buf);
- sprops.user_dir = _wcsdup(buf);
+ if (GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR), buf) != 0)
+ sprops.user_dir = _wcsdup(buf);
}
sprops.file_separator = "\\";
--- a/jdk/src/windows/native/sun/management/FileSystemImpl.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/sun/management/FileSystemImpl.c Tue Apr 12 14:23:03 2011 -0700
@@ -37,45 +37,6 @@
#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
/*
- * Function prototypes for security functions - we can't statically
- * link because these functions aren't on Windows 9x.
- */
-typedef BOOL (WINAPI *GetFileSecurityFunc)
- (LPCTSTR lpFileName, SECURITY_INFORMATION RequestedInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength,
- LPDWORD lpnLengthNeeded);
-
-typedef BOOL (WINAPI *GetSecurityDescriptorOwnerFunc)
- (PSECURITY_DESCRIPTOR pSecurityDescriptor, PSID *pOwner,
- LPBOOL lpbOwnerDefaulted);
-
-typedef BOOL (WINAPI *GetSecurityDescriptorDaclFunc)
- (PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent,
- PACL *pDacl, LPBOOL lpbDaclDefaulted);
-
-typedef BOOL (WINAPI *GetAclInformationFunc)
- (PACL pAcl, LPVOID pAclInformation, DWORD nAclInformationLength,
- ACL_INFORMATION_CLASS dwAclInformationClass);
-
-typedef BOOL (WINAPI *GetAceFunc)
- (PACL pAcl, DWORD dwAceIndex, LPVOID *pAce);
-
-typedef BOOL (WINAPI *EqualSidFunc)(PSID pSid1, PSID pSid2);
-
-
-/* Addresses of the security functions */
-static GetFileSecurityFunc GetFileSecurity_func;
-static GetSecurityDescriptorOwnerFunc GetSecurityDescriptorOwner_func;
-static GetSecurityDescriptorDaclFunc GetSecurityDescriptorDacl_func;
-static GetAclInformationFunc GetAclInformation_func;
-static GetAceFunc GetAce_func;
-static EqualSidFunc EqualSid_func;
-
-/* True if this OS is NT kernel based (NT/2000/XP) */
-static int isNT;
-
-
-/*
* Returns JNI_TRUE if the specified file is on a file system that supports
* persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
* returns false).
@@ -165,7 +126,7 @@
SECURITY_INFORMATION info =
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
- (*GetFileSecurity_func)(path, info , 0, 0, &len);
+ GetFileSecurityA(path, info , 0, 0, &len);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
return NULL;
@@ -174,7 +135,7 @@
if (sd == NULL) {
JNU_ThrowOutOfMemoryError(env, 0);
} else {
- if (!(*GetFileSecurity_func)(path, info, sd, len, &len)) {
+ if (!(*GetFileSecurityA)(path, info, sd, len, &len)) {
JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
free(sd);
return NULL;
@@ -191,7 +152,7 @@
SID* owner;
BOOL defaulted;
- if (!(*GetSecurityDescriptorOwner_func)(sd, &owner, &defaulted)) {
+ if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorOwner failed");
return NULL;
}
@@ -206,7 +167,7 @@
ACL *acl;
int defaulted, present;
- if (!(*GetSecurityDescriptorDacl_func)(sd, &present, &acl, &defaulted)) {
+ if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorDacl failed");
return NULL;
}
@@ -235,8 +196,8 @@
/*
* Get the ACE count
*/
- if (!(*GetAclInformation_func)(acl, (void *) &acl_size_info, sizeof(acl_size_info),
- AclSizeInformation)) {
+ if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
+ AclSizeInformation)) {
JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed");
return JNI_FALSE;
}
@@ -250,7 +211,7 @@
ACCESS_ALLOWED_ACE *access;
SID* sid;
- if (!(*GetAce_func)(acl, i, &ace)) {
+ if (!GetAce(acl, i, &ace)) {
JNU_ThrowIOExceptionWithLastError(env, "GetAce failed");
return -1;
}
@@ -280,51 +241,7 @@
JNIEXPORT void JNICALL Java_sun_management_FileSystemImpl_init0
(JNIEnv *env, jclass ignored)
{
- OSVERSIONINFO ver;
- HINSTANCE hInst;
-
- /*
- * Get the OS version. If dwPlatformId is VER_PLATFORM_WIN32_NT
- * it means we're running on a Windows NT, 2000, or XP machine.
- */
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- isNT = (ver.dwPlatformId == VER_PLATFORM_WIN32_NT);
- if (!isNT) {
- return;
- }
-
- /*
- * On NT/2000/XP we need the addresses of the security functions
- */
- hInst = LoadLibrary("ADVAPI32.DLL");
- if (hInst == NULL) {
- JNU_ThrowIOExceptionWithLastError(env, "Unable to load ADVAPI32.DLL");
- return;
- }
-
-
- GetFileSecurity_func = (GetFileSecurityFunc)GetProcAddress(hInst, "GetFileSecurityA");
- GetSecurityDescriptorOwner_func =
- (GetSecurityDescriptorOwnerFunc)GetProcAddress(hInst, "GetSecurityDescriptorOwner");
- GetSecurityDescriptorDacl_func =
- (GetSecurityDescriptorDaclFunc)GetProcAddress(hInst, "GetSecurityDescriptorDacl");
- GetAclInformation_func =
- (GetAclInformationFunc)GetProcAddress(hInst, "GetAclInformation");
- GetAce_func = (GetAceFunc)GetProcAddress(hInst, "GetAce");
- EqualSid_func = (EqualSidFunc)GetProcAddress(hInst, "EqualSid");
-
- if (GetFileSecurity_func == NULL ||
- GetSecurityDescriptorDacl_func == NULL ||
- GetSecurityDescriptorDacl_func == NULL ||
- GetAclInformation_func == NULL ||
- GetAce_func == NULL ||
- EqualSid_func == NULL)
- {
- JNU_ThrowIOExceptionWithLastError(env,
- "Unable to get address of security functions");
- return;
- }
+ /* nothing to do */
}
/*
@@ -339,10 +256,6 @@
jboolean isCopy;
const char* path;
- if (!isNT) {
- return JNI_FALSE;
- }
-
path = JNU_GetStringPlatformChars(env, str, &isCopy);
if (path != NULL) {
res = isSecuritySupported(env, path);
--- a/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Tue Apr 12 14:23:03 2011 -0700
@@ -24,7 +24,7 @@
*/
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
@@ -36,6 +36,7 @@
#include <windows.h>
#include <aclapi.h>
#include <winioctl.h>
+#include <Sddl.h>
#include "jni.h"
#include "jni_util.h"
@@ -77,40 +78,20 @@
/**
- * Win32 APIs not defined in Visual Studio 2003 header files
+ * Win32 APIs not available in Windows XP
*/
-
-typedef enum {
- FindStreamInfoStandard
-} MY_STREAM_INFO_LEVELS;
-
-typedef struct _MY_WIN32_FIND_STREAM_DATA {
- LARGE_INTEGER StreamSize;
- WCHAR cStreamName[MAX_PATH + 36];
-} MY_WIN32_FIND_STREAM_DATA;
-
-typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, MY_STREAM_INFO_LEVELS, LPVOID, DWORD);
+typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, STREAM_INFO_LEVELS, LPVOID, DWORD);
typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);
typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
-typedef BOOL (WINAPI* CreateHardLinkProc) (LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
-typedef BOOL (WINAPI* ConvertSidToStringSidProc) (PSID, LPWSTR*);
-typedef BOOL (WINAPI* ConvertStringSidToSidProc) (LPWSTR, PSID*);
-typedef DWORD (WINAPI* GetLengthSidProc) (PSID);
-
static FindFirstStream_Proc FindFirstStream_func;
static FindNextStream_Proc FindNextStream_func;
static CreateSymbolicLinkProc CreateSymbolicLink_func;
-static CreateHardLinkProc CreateHardLink_func;
static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
-static ConvertSidToStringSidProc ConvertSidToStringSid_func;
-static ConvertStringSidToSidProc ConvertStringSidToSid_func;
-static GetLengthSidProc GetLengthSid_func;
-
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
"(I)V", lastError);
@@ -190,33 +171,23 @@
backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
-
- h = LoadLibrary("kernel32");
- if (h != INVALID_HANDLE_VALUE) {
+ // get handle to kernel32
+ if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
+ (LPCWSTR)&CreateFileW, &h) != 0)
+ {
+ // requires Windows Server 2003 or newer
FindFirstStream_func =
(FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
FindNextStream_func =
(FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
+
+ // requires Windows Vista or newer
CreateSymbolicLink_func =
(CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
- CreateHardLink_func =
- (CreateHardLinkProc)GetProcAddress(h, "CreateHardLinkW");
GetFinalPathNameByHandle_func =
(GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
- FreeLibrary(h);
}
-
- h = LoadLibrary("advapi32");
- if (h != INVALID_HANDLE_VALUE) {
- ConvertSidToStringSid_func =
- (ConvertSidToStringSidProc)GetProcAddress(h, "ConvertSidToStringSidW");
- ConvertStringSidToSid_func =
- (ConvertStringSidToSidProc)GetProcAddress(h, "ConvertStringSidToSidW");
- GetLengthSid_func =
- (GetLengthSidProc)GetProcAddress(h, "GetLengthSid");
- FreeLibrary(h);
- }
-
}
JNIEXPORT jstring JNICALL
@@ -413,7 +384,7 @@
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass this,
jlong address, jobject obj)
{
- MY_WIN32_FIND_STREAM_DATA data;
+ WIN32_FIND_STREAM_DATA data;
LPCWSTR lpFileName = jlong_to_ptr(address);
HANDLE handle;
@@ -443,7 +414,7 @@
Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
jlong handle)
{
- MY_WIN32_FIND_STREAM_DATA data;
+ WIN32_FIND_STREAM_DATA data;
HANDLE h = (HANDLE)jlong_to_ptr(handle);
if (FindNextStream_func == NULL) {
@@ -909,12 +880,7 @@
jclass this, jlong address)
{
PSID sid = jlong_to_ptr(address);
-
- if (GetLengthSid_func == NULL) {
- JNU_ThrowInternalError(env, "Should not get here");
- return 0;
- }
- return (jint)(*GetLengthSid_func)(sid);
+ return (jint)GetLengthSid(sid);
}
@@ -924,13 +890,7 @@
{
PSID sid = jlong_to_ptr(address);
LPWSTR string;
-
- if (ConvertSidToStringSid_func == NULL) {
- JNU_ThrowInternalError(env, "Should not get here");
- return NULL;
- }
-
- if ((*ConvertSidToStringSid_func)(sid, &string) == 0) {
+ if (ConvertSidToStringSidW(sid, &string) == 0) {
throwWindowsException(env, GetLastError());
return NULL;
} else {
@@ -947,15 +907,8 @@
{
LPWSTR lpStringSid = jlong_to_ptr(address);
PSID pSid;
-
- if (ConvertStringSidToSid_func == NULL) {
- JNU_ThrowInternalError(env, "Should not get here");
- return (jlong)0;
- }
-
- if ((*ConvertStringSidToSid_func)(lpStringSid, &pSid) == 0)
+ if (ConvertStringSidToSidW(lpStringSid, &pSid) == 0)
throwWindowsException(env, GetLastError());
-
return ptr_to_jlong(pSid);
}
@@ -1137,11 +1090,7 @@
LPCWSTR newFile = jlong_to_ptr(newFileAddress);
LPCWSTR existingFile = jlong_to_ptr(existingFileAddress);
- if (CreateHardLink_func == NULL) {
- JNU_ThrowInternalError(env, "Should not get here");
- return;
- }
- if ((*CreateHardLink_func)(newFile, existingFile, NULL) == 0)
+ if (CreateHardLinkW(newFile, existingFile, NULL) == 0)
throwWindowsException(env, GetLastError());
}
--- a/jdk/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Tue Apr 12 14:23:03 2011 -0700
@@ -33,11 +33,6 @@
#include <jni.h>
#include "sun_security_provider_NativeSeedGenerator.h"
-/* Typedefs for runtime linking. */
-typedef BOOL (WINAPI *CryptAcquireContextType)(HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
-typedef BOOL (WINAPI *CryptGenRandomType)(HCRYPTPROV, DWORD, BYTE*);
-typedef BOOL (WINAPI *CryptReleaseContextType)(HCRYPTPROV, DWORD);
-
/*
* Get a random seed from the MS CryptoAPI. Return true if successful, false
* otherwise.
@@ -49,48 +44,27 @@
JNIEXPORT jboolean JNICALL Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed
(JNIEnv *env, jclass clazz, jbyteArray randArray)
{
- HMODULE lib;
- CryptAcquireContextType acquireContext;
- CryptGenRandomType genRandom;
- CryptReleaseContextType releaseContext;
-
HCRYPTPROV hCryptProv;
jboolean result = JNI_FALSE;
jsize numBytes;
jbyte* randBytes;
- lib = LoadLibrary("ADVAPI32.DLL");
- if (lib == NULL) {
- return result;
- }
-
- acquireContext = (CryptAcquireContextType)GetProcAddress(lib, "CryptAcquireContextA");
- genRandom = (CryptGenRandomType)GetProcAddress(lib, "CryptGenRandom");
- releaseContext = (CryptReleaseContextType)GetProcAddress(lib, "CryptReleaseContext");
-
- if (acquireContext == NULL || genRandom == NULL || releaseContext == NULL) {
- FreeLibrary(lib);
- return result;
- }
-
- if (acquireContext(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL, 0) == FALSE) {
+ if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL, 0) == FALSE) {
/* If CSP context hasn't been created, create one. */
- if (acquireContext(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL,
+ if (CryptAcquireContextA(&hCryptProv, "J2SE", NULL, PROV_RSA_FULL,
CRYPT_NEWKEYSET) == FALSE) {
- FreeLibrary(lib);
return result;
}
}
numBytes = (*env)->GetArrayLength(env, randArray);
randBytes = (*env)->GetByteArrayElements(env, randArray, NULL);
- if (genRandom(hCryptProv, numBytes, randBytes)) {
+ if (CryptGenRandom(hCryptProv, numBytes, randBytes)) {
result = JNI_TRUE;
}
(*env)->ReleaseByteArrayElements(env, randArray, randBytes, 0);
- releaseContext(hCryptProv, 0);
- FreeLibrary(lib);
+ CryptReleaseContext(hCryptProv, 0);
return result;
}
--- a/jdk/test/java/lang/Character/CheckScript.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/lang/Character/CheckScript.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,34 +1,58 @@
+
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
/**
* @test
- * @bug 6945564 6959267
+ * @bug 6945564 6959267 7033561
* @summary Check that the j.l.Character.UnicodeScript
*/
import java.io.*;
-import java.lang.reflect.*;
import java.util.*;
import java.util.regex.*;
import java.lang.Character.UnicodeScript;
public class CheckScript {
- static BufferedReader open(String[] args) throws FileNotFoundException {
+ public static void main(String[] args) throws Exception {
+ File fScripts;
+ File fAliases;
if (args.length == 0) {
- return new BufferedReader(new FileReader(new File(System.getProperty("test.src", "."), "Scripts.txt")));
- } else if (args.length == 1) {
- return new BufferedReader(new FileReader(args[0]));
+ fScripts = new File(System.getProperty("test.src", "."), "Scripts.txt");
+ fAliases = new File(System.getProperty("test.src", "."), "PropertyValueAliases.txt");
+ } else if (args.length == 2) {
+ fScripts = new File(args[0]);
+ fAliases = new File(args[1]);
} else {
- System.out.println("java CharacterScript Scripts.txt");
+ System.out.println("java CharacterScript Scripts.txt PropertyValueAliases.txt");
throw new RuntimeException("Datafile name should be specified.");
}
- }
-
- public static void main(String[] args) throws Exception {
Matcher m = Pattern.compile("(\\p{XDigit}+)(?:\\.{2}(\\p{XDigit}+))?\\s+;\\s+(\\w+)\\s+#.*").matcher("");
String line = null;
HashMap<String,ArrayList<Integer>> scripts = new HashMap<>();
- try (BufferedReader sbfr = open(args)) {
+ try (BufferedReader sbfr = new BufferedReader(new FileReader(fScripts))) {
while ((line = sbfr.readLine()) != null) {
if (line.length() <= 1 || line.charAt(0) == '#') {
continue;
@@ -107,5 +131,29 @@
}
}
}
+ // check all aliases
+ m = Pattern.compile("sc\\s*;\\s*(\\p{Alpha}{4})\\s*;\\s*([\\p{Alpha}|_]+)\\s*.*").matcher("");
+ line = null;
+ try (BufferedReader sbfr = new BufferedReader(new FileReader(fAliases))) {
+ while ((line = sbfr.readLine()) != null) {
+ if (line.length() <= 1 || line.charAt(0) == '#') {
+ continue;
+ }
+ m.reset(line);
+ if (m.matches()) {
+ String alias = m.group(1);
+ String name = m.group(2);
+ // HRKT -> Katakana_Or_Hiragana not supported
+ if ("HRKT".equals(alias.toUpperCase(Locale.ENGLISH)))
+ continue;
+ if (Character.UnicodeScript.forName(alias) !=
+ Character.UnicodeScript.forName(name)) {
+ throw new RuntimeException(
+ "UnicodeScript failed: alias<" + alias +
+ "> does not map to <" + name + ">");
+ }
+ }
+ }
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Character/PropertyValueAliases.txt Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,1178 @@
+# PropertyValueAliases-6.0.0.txt
+# Date: 2010-07-17, 22:44:06 GMT [MD]
+#
+# Unicode Character Database
+# Copyright (c) 1991-2010 Unicode, Inc.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# This file contains aliases for property values used in the UCD.
+# These names can be used for XML formats of UCD data, for regular-expression
+# property tests, and other programmatic textual descriptions of Unicode data.
+# For information on which properties are normative, see UCD.html.
+#
+# The names may be translated in appropriate environments, and additional
+# aliases may be useful.
+#
+# FORMAT
+#
+# Each line describes a property value name.
+# This consists of three or more fields, separated by semicolons.
+#
+# First Field: The first field describes the property for which that
+# property value name is used.
+#
+# Second Field: The second field is an abbreviated name.
+# If there is no abbreviated name available, the field is marked with "n/a".
+#
+# Third Field: The third field is a long name.
+#
+# In the case of ccc, there are 4 fields. The second field is numeric, third
+# is abbreviated, and fourth is long.
+#
+# The above are the preferred aliases. Other aliases may be listed in additional fields.
+#
+# Loose matching should be applied to all property names and property values, with
+# the exception of String Property values. With loose matching of property names and
+# values, the case distinctions, whitespace, and '_' are ignored. For Numeric Property
+# values, numeric equivalencies are applied: thus "01.00" is equivalent to "1".
+#
+# NOTE: Property value names are NOT unique across properties. For example:
+#
+# AL means Arabic Letter for the Bidi_Class property, and
+# AL means Above_Left for the Combining_Class property, and
+# AL means Alphabetic for the Line_Break property.
+#
+# In addition, some property names may be the same as some property value names.
+# For example:
+#
+# sc means the Script property, and
+# Sc means the General_Category property value Currency_Symbol (Sc)
+#
+# The combination of property value and property name is, however, unique.
+#
+# For more information, see UTS #18: Unicode Regular Expressions
+# ================================================
+
+
+# ASCII_Hex_Digit (AHex)
+
+AHex; N ; No ; F ; False
+AHex; Y ; Yes ; T ; True
+
+# Age (age)
+
+age; n/a ; 1.1
+age; n/a ; 2.0
+age; n/a ; 2.1
+age; n/a ; 3.0
+age; n/a ; 3.1
+age; n/a ; 3.2
+age; n/a ; 4.0
+age; n/a ; 4.1
+age; n/a ; 5.0
+age; n/a ; 5.1
+age; n/a ; 5.2
+age; n/a ; 6.0
+age; n/a ; unassigned
+
+# Alphabetic (Alpha)
+
+Alpha; N ; No ; F ; False
+Alpha; Y ; Yes ; T ; True
+
+# Bidi_Class (bc)
+
+bc ; AL ; Arabic_Letter
+bc ; AN ; Arabic_Number
+bc ; B ; Paragraph_Separator
+bc ; BN ; Boundary_Neutral
+bc ; CS ; Common_Separator
+bc ; EN ; European_Number
+bc ; ES ; European_Separator
+bc ; ET ; European_Terminator
+bc ; L ; Left_To_Right
+bc ; LRE ; Left_To_Right_Embedding
+bc ; LRO ; Left_To_Right_Override
+bc ; NSM ; Nonspacing_Mark
+bc ; ON ; Other_Neutral
+bc ; PDF ; Pop_Directional_Format
+bc ; R ; Right_To_Left
+bc ; RLE ; Right_To_Left_Embedding
+bc ; RLO ; Right_To_Left_Override
+bc ; S ; Segment_Separator
+bc ; WS ; White_Space
+
+# Bidi_Control (Bidi_C)
+
+Bidi_C; N ; No ; F ; False
+Bidi_C; Y ; Yes ; T ; True
+
+# Bidi_Mirrored (Bidi_M)
+
+Bidi_M; N ; No ; F ; False
+Bidi_M; Y ; Yes ; T ; True
+
+# Bidi_Mirroring_Glyph (bmg)
+
+# @missing: 0000..10FFFF; Bidi_Mirroring_Glyph; <none>
+
+# Block (blk)
+
+blk; n/a ; Aegean_Numbers
+blk; n/a ; Alchemical_Symbols
+blk; n/a ; Alphabetic_Presentation_Forms
+blk; n/a ; Ancient_Greek_Musical_Notation
+blk; n/a ; Ancient_Greek_Numbers
+blk; n/a ; Ancient_Symbols
+blk; n/a ; Arabic
+blk; n/a ; Arabic_Presentation_Forms_A ; Arabic_Presentation_Forms-A
+blk; n/a ; Arabic_Presentation_Forms_B
+blk; n/a ; Arabic_Supplement
+blk; n/a ; Armenian
+blk; n/a ; Arrows
+blk; n/a ; Avestan
+blk; n/a ; Balinese
+blk; n/a ; Bamum
+blk; n/a ; Bamum_Supplement
+blk; n/a ; Basic_Latin ; ASCII
+blk; n/a ; Batak
+blk; n/a ; Bengali
+blk; n/a ; Block_Elements
+blk; n/a ; Bopomofo
+blk; n/a ; Bopomofo_Extended
+blk; n/a ; Box_Drawing
+blk; n/a ; Brahmi
+blk; n/a ; Braille_Patterns
+blk; n/a ; Buginese
+blk; n/a ; Buhid
+blk; n/a ; Byzantine_Musical_Symbols
+blk; n/a ; Carian
+blk; n/a ; Cham
+blk; n/a ; Cherokee
+blk; n/a ; CJK_Compatibility
+blk; n/a ; CJK_Compatibility_Forms
+blk; n/a ; CJK_Compatibility_Ideographs
+blk; n/a ; CJK_Compatibility_Ideographs_Supplement
+blk; n/a ; CJK_Radicals_Supplement
+blk; n/a ; CJK_Strokes
+blk; n/a ; CJK_Symbols_And_Punctuation
+blk; n/a ; CJK_Unified_Ideographs
+blk; n/a ; CJK_Unified_Ideographs_Extension_A
+blk; n/a ; CJK_Unified_Ideographs_Extension_B
+blk; n/a ; CJK_Unified_Ideographs_Extension_C
+blk; n/a ; CJK_Unified_Ideographs_Extension_D
+blk; n/a ; Combining_Diacritical_Marks
+blk; n/a ; Combining_Diacritical_Marks_For_Symbols; Combining_Marks_For_Symbols
+blk; n/a ; Combining_Diacritical_Marks_Supplement
+blk; n/a ; Combining_Half_Marks
+blk; n/a ; Common_Indic_Number_Forms
+blk; n/a ; Control_Pictures
+blk; n/a ; Coptic
+blk; n/a ; Counting_Rod_Numerals
+blk; n/a ; Cuneiform
+blk; n/a ; Cuneiform_Numbers_And_Punctuation
+blk; n/a ; Currency_Symbols
+blk; n/a ; Cypriot_Syllabary
+blk; n/a ; Cyrillic
+blk; n/a ; Cyrillic_Extended_A
+blk; n/a ; Cyrillic_Extended_B
+blk; n/a ; Cyrillic_Supplement ; Cyrillic_Supplementary
+blk; n/a ; Deseret
+blk; n/a ; Devanagari
+blk; n/a ; Devanagari_Extended
+blk; n/a ; Dingbats
+blk; n/a ; Domino_Tiles
+blk; n/a ; Egyptian_Hieroglyphs
+blk; n/a ; Emoticons
+blk; n/a ; Enclosed_Alphanumeric_Supplement
+blk; n/a ; Enclosed_Alphanumerics
+blk; n/a ; Enclosed_CJK_Letters_And_Months
+blk; n/a ; Enclosed_Ideographic_Supplement
+blk; n/a ; Ethiopic
+blk; n/a ; Ethiopic_Extended
+blk; n/a ; Ethiopic_Extended_A
+blk; n/a ; Ethiopic_Supplement
+blk; n/a ; General_Punctuation
+blk; n/a ; Geometric_Shapes
+blk; n/a ; Georgian
+blk; n/a ; Georgian_Supplement
+blk; n/a ; Glagolitic
+blk; n/a ; Gothic
+blk; n/a ; Greek_And_Coptic ; Greek
+blk; n/a ; Greek_Extended
+blk; n/a ; Gujarati
+blk; n/a ; Gurmukhi
+blk; n/a ; Halfwidth_And_Fullwidth_Forms
+blk; n/a ; Hangul_Compatibility_Jamo
+blk; n/a ; Hangul_Jamo
+blk; n/a ; Hangul_Jamo_Extended_A
+blk; n/a ; Hangul_Jamo_Extended_B
+blk; n/a ; Hangul_Syllables
+blk; n/a ; Hanunoo
+blk; n/a ; Hebrew
+blk; n/a ; High_Private_Use_Surrogates
+blk; n/a ; High_Surrogates
+blk; n/a ; Hiragana
+blk; n/a ; Ideographic_Description_Characters
+blk; n/a ; Imperial_Aramaic
+blk; n/a ; Inscriptional_Pahlavi
+blk; n/a ; Inscriptional_Parthian
+blk; n/a ; IPA_Extensions
+blk; n/a ; Javanese
+blk; n/a ; Kaithi
+blk; n/a ; Kana_Supplement
+blk; n/a ; Kanbun
+blk; n/a ; Kangxi_Radicals
+blk; n/a ; Kannada
+blk; n/a ; Katakana
+blk; n/a ; Katakana_Phonetic_Extensions
+blk; n/a ; Kayah_Li
+blk; n/a ; Kharoshthi
+blk; n/a ; Khmer
+blk; n/a ; Khmer_Symbols
+blk; n/a ; Lao
+blk; n/a ; Latin_1_Supplement ; Latin_1
+blk; n/a ; Latin_Extended_A
+blk; n/a ; Latin_Extended_Additional
+blk; n/a ; Latin_Extended_B
+blk; n/a ; Latin_Extended_C
+blk; n/a ; Latin_Extended_D
+blk; n/a ; Lepcha
+blk; n/a ; Letterlike_Symbols
+blk; n/a ; Limbu
+blk; n/a ; Linear_B_Ideograms
+blk; n/a ; Linear_B_Syllabary
+blk; n/a ; Lisu
+blk; n/a ; Low_Surrogates
+blk; n/a ; Lycian
+blk; n/a ; Lydian
+blk; n/a ; Mahjong_Tiles
+blk; n/a ; Malayalam
+blk; n/a ; Mandaic
+blk; n/a ; Mathematical_Alphanumeric_Symbols
+blk; n/a ; Mathematical_Operators
+blk; n/a ; Meetei_Mayek
+blk; n/a ; Miscellaneous_Mathematical_Symbols_A
+blk; n/a ; Miscellaneous_Mathematical_Symbols_B
+blk; n/a ; Miscellaneous_Symbols
+blk; n/a ; Miscellaneous_Symbols_And_Arrows
+blk; n/a ; Miscellaneous_Symbols_And_Pictographs
+blk; n/a ; Miscellaneous_Technical
+blk; n/a ; Modifier_Tone_Letters
+blk; n/a ; Mongolian
+blk; n/a ; Musical_Symbols
+blk; n/a ; Myanmar
+blk; n/a ; Myanmar_Extended_A
+blk; n/a ; New_Tai_Lue
+blk; n/a ; NKo
+blk; n/a ; No_Block
+blk; n/a ; Number_Forms
+blk; n/a ; Ogham
+blk; n/a ; Ol_Chiki
+blk; n/a ; Old_Italic
+blk; n/a ; Old_Persian
+blk; n/a ; Old_South_Arabian
+blk; n/a ; Old_Turkic
+blk; n/a ; Optical_Character_Recognition
+blk; n/a ; Oriya
+blk; n/a ; Osmanya
+blk; n/a ; Phags_Pa
+blk; n/a ; Phaistos_Disc
+blk; n/a ; Phoenician
+blk; n/a ; Phonetic_Extensions
+blk; n/a ; Phonetic_Extensions_Supplement
+blk; n/a ; Playing_Cards
+blk; n/a ; Private_Use_Area ; Private_Use
+blk; n/a ; Rejang
+blk; n/a ; Rumi_Numeral_Symbols
+blk; n/a ; Runic
+blk; n/a ; Samaritan
+blk; n/a ; Saurashtra
+blk; n/a ; Shavian
+blk; n/a ; Sinhala
+blk; n/a ; Small_Form_Variants
+blk; n/a ; Spacing_Modifier_Letters
+blk; n/a ; Specials
+blk; n/a ; Sundanese
+blk; n/a ; Superscripts_And_Subscripts
+blk; n/a ; Supplemental_Arrows_A
+blk; n/a ; Supplemental_Arrows_B
+blk; n/a ; Supplemental_Mathematical_Operators
+blk; n/a ; Supplemental_Punctuation
+blk; n/a ; Supplementary_Private_Use_Area_A
+blk; n/a ; Supplementary_Private_Use_Area_B
+blk; n/a ; Syloti_Nagri
+blk; n/a ; Syriac
+blk; n/a ; Tagalog
+blk; n/a ; Tagbanwa
+blk; n/a ; Tags
+blk; n/a ; Tai_Le
+blk; n/a ; Tai_Tham
+blk; n/a ; Tai_Viet
+blk; n/a ; Tai_Xuan_Jing_Symbols
+blk; n/a ; Tamil
+blk; n/a ; Telugu
+blk; n/a ; Thaana
+blk; n/a ; Thai
+blk; n/a ; Tibetan
+blk; n/a ; Tifinagh
+blk; n/a ; Transport_And_Map_Symbols
+blk; n/a ; Ugaritic
+blk; n/a ; Unified_Canadian_Aboriginal_Syllabics; Canadian_Syllabics
+blk; n/a ; Unified_Canadian_Aboriginal_Syllabics_Extended
+blk; n/a ; Vai
+blk; n/a ; Variation_Selectors
+blk; n/a ; Variation_Selectors_Supplement
+blk; n/a ; Vedic_Extensions
+blk; n/a ; Vertical_Forms
+blk; n/a ; Yi_Radicals
+blk; n/a ; Yi_Syllables
+blk; n/a ; Yijing_Hexagram_Symbols
+
+# Canonical_Combining_Class (ccc)
+
+ccc; 0; NR ; Not_Reordered
+ccc; 1; OV ; Overlay
+ccc; 7; NK ; Nukta
+ccc; 8; KV ; Kana_Voicing
+ccc; 9; VR ; Virama
+ccc; 200; ATBL ; Attached_Below_Left
+ccc; 202; ATB ; Attached_Below
+ccc; 214; ATA ; Attached_Above
+ccc; 216; ATAR ; Attached_Above_Right
+ccc; 218; BL ; Below_Left
+ccc; 220; B ; Below
+ccc; 222; BR ; Below_Right
+ccc; 224; L ; Left
+ccc; 226; R ; Right
+ccc; 228; AL ; Above_Left
+ccc; 230; A ; Above
+ccc; 232; AR ; Above_Right
+ccc; 233; DB ; Double_Below
+ccc; 234; DA ; Double_Above
+ccc; 240; IS ; Iota_Subscript
+
+# Case_Folding (cf)
+
+# @missing: 0000..10FFFF; Case_Folding; <code point>
+
+# Case_Ignorable (CI)
+
+CI ; N ; No ; F ; False
+CI ; Y ; Yes ; T ; True
+
+# Cased (Cased)
+
+Cased; N ; No ; F ; False
+Cased; Y ; Yes ; T ; True
+
+# Changes_When_Casefolded (CWCF)
+
+CWCF; N ; No ; F ; False
+CWCF; Y ; Yes ; T ; True
+
+# Changes_When_Casemapped (CWCM)
+
+CWCM; N ; No ; F ; False
+CWCM; Y ; Yes ; T ; True
+
+# Changes_When_Lowercased (CWL)
+
+CWL; N ; No ; F ; False
+CWL; Y ; Yes ; T ; True
+
+# Changes_When_NFKC_Casefolded (CWKCF)
+
+CWKCF; N ; No ; F ; False
+CWKCF; Y ; Yes ; T ; True
+
+# Changes_When_Titlecased (CWT)
+
+CWT; N ; No ; F ; False
+CWT; Y ; Yes ; T ; True
+
+# Changes_When_Uppercased (CWU)
+
+CWU; N ; No ; F ; False
+CWU; Y ; Yes ; T ; True
+
+# Composition_Exclusion (CE)
+
+CE ; N ; No ; F ; False
+CE ; Y ; Yes ; T ; True
+
+# Dash (Dash)
+
+Dash; N ; No ; F ; False
+Dash; Y ; Yes ; T ; True
+
+# Decomposition_Mapping (dm)
+
+# @missing: 0000..10FFFF; Decomposition_Mapping; <code point>
+
+# Decomposition_Type (dt)
+
+dt ; Can ; Canonical ; can
+dt ; Com ; Compat ; com
+dt ; Enc ; Circle ; enc
+dt ; Fin ; Final ; fin
+dt ; Font ; font
+dt ; Fra ; Fraction ; fra
+dt ; Init ; Initial ; init
+dt ; Iso ; Isolated ; iso
+dt ; Med ; Medial ; med
+dt ; Nar ; Narrow ; nar
+dt ; Nb ; Nobreak ; nb
+dt ; None ; none
+dt ; Sml ; Small ; sml
+dt ; Sqr ; Square ; sqr
+dt ; Sub ; sub
+dt ; Sup ; Super ; sup
+dt ; Vert ; Vertical ; vert
+dt ; Wide ; wide
+
+# Default_Ignorable_Code_Point (DI)
+
+DI ; N ; No ; F ; False
+DI ; Y ; Yes ; T ; True
+
+# Deprecated (Dep)
+
+Dep; N ; No ; F ; False
+Dep; Y ; Yes ; T ; True
+
+# Diacritic (Dia)
+
+Dia; N ; No ; F ; False
+Dia; Y ; Yes ; T ; True
+
+# East_Asian_Width (ea)
+
+ea ; A ; Ambiguous
+ea ; F ; Fullwidth
+ea ; H ; Halfwidth
+ea ; N ; Neutral
+ea ; Na ; Narrow
+ea ; W ; Wide
+
+# Expands_On_NFC (XO_NFC)
+
+XO_NFC; N ; No ; F ; False
+XO_NFC; Y ; Yes ; T ; True
+
+# Expands_On_NFD (XO_NFD)
+
+XO_NFD; N ; No ; F ; False
+XO_NFD; Y ; Yes ; T ; True
+
+# Expands_On_NFKC (XO_NFKC)
+
+XO_NFKC; N ; No ; F ; False
+XO_NFKC; Y ; Yes ; T ; True
+
+# Expands_On_NFKD (XO_NFKD)
+
+XO_NFKD; N ; No ; F ; False
+XO_NFKD; Y ; Yes ; T ; True
+
+# Extender (Ext)
+
+Ext; N ; No ; F ; False
+Ext; Y ; Yes ; T ; True
+
+# FC_NFKC_Closure (FC_NFKC)
+
+# @missing: 0000..10FFFF; FC_NFKC_Closure; <code point>
+
+# Full_Composition_Exclusion (Comp_Ex)
+
+Comp_Ex; N ; No ; F ; False
+Comp_Ex; Y ; Yes ; T ; True
+
+# General_Category (gc)
+
+gc ; C ; Other # Cc | Cf | Cn | Co | Cs
+gc ; Cc ; Control ; cntrl
+gc ; Cf ; Format
+gc ; Cn ; Unassigned
+gc ; Co ; Private_Use
+gc ; Cs ; Surrogate
+gc ; L ; Letter # Ll | Lm | Lo | Lt | Lu
+gc ; LC ; Cased_Letter # Ll | Lt | Lu
+gc ; Ll ; Lowercase_Letter
+gc ; Lm ; Modifier_Letter
+gc ; Lo ; Other_Letter
+gc ; Lt ; Titlecase_Letter
+gc ; Lu ; Uppercase_Letter
+gc ; M ; Mark # Mc | Me | Mn
+gc ; Mc ; Spacing_Mark
+gc ; Me ; Enclosing_Mark
+gc ; Mn ; Nonspacing_Mark
+gc ; N ; Number # Nd | Nl | No
+gc ; Nd ; Decimal_Number ; digit
+gc ; Nl ; Letter_Number
+gc ; No ; Other_Number
+gc ; P ; Punctuation ; punct # Pc | Pd | Pe | Pf | Pi | Po | Ps
+gc ; Pc ; Connector_Punctuation
+gc ; Pd ; Dash_Punctuation
+gc ; Pe ; Close_Punctuation
+gc ; Pf ; Final_Punctuation
+gc ; Pi ; Initial_Punctuation
+gc ; Po ; Other_Punctuation
+gc ; Ps ; Open_Punctuation
+gc ; S ; Symbol # Sc | Sk | Sm | So
+gc ; Sc ; Currency_Symbol
+gc ; Sk ; Modifier_Symbol
+gc ; Sm ; Math_Symbol
+gc ; So ; Other_Symbol
+gc ; Z ; Separator # Zl | Zp | Zs
+gc ; Zl ; Line_Separator
+gc ; Zp ; Paragraph_Separator
+gc ; Zs ; Space_Separator
+
+# Grapheme_Base (Gr_Base)
+
+Gr_Base; N ; No ; F ; False
+Gr_Base; Y ; Yes ; T ; True
+
+# Grapheme_Cluster_Break (GCB)
+
+GCB; CN ; Control
+GCB; CR ; CR
+GCB; EX ; Extend
+GCB; L ; L
+GCB; LF ; LF
+GCB; LV ; LV
+GCB; LVT ; LVT
+GCB; PP ; Prepend
+GCB; SM ; SpacingMark
+GCB; T ; T
+GCB; V ; V
+GCB; XX ; Other
+
+# Grapheme_Extend (Gr_Ext)
+
+Gr_Ext; N ; No ; F ; False
+Gr_Ext; Y ; Yes ; T ; True
+
+# Grapheme_Link (Gr_Link)
+
+Gr_Link; N ; No ; F ; False
+Gr_Link; Y ; Yes ; T ; True
+
+# Hangul_Syllable_Type (hst)
+
+hst; L ; Leading_Jamo
+hst; LV ; LV_Syllable
+hst; LVT ; LVT_Syllable
+hst; NA ; Not_Applicable
+hst; T ; Trailing_Jamo
+hst; V ; Vowel_Jamo
+
+# Hex_Digit (Hex)
+
+Hex; N ; No ; F ; False
+Hex; Y ; Yes ; T ; True
+
+# Hyphen (Hyphen)
+
+Hyphen; N ; No ; F ; False
+Hyphen; Y ; Yes ; T ; True
+
+# IDS_Binary_Operator (IDSB)
+
+IDSB; N ; No ; F ; False
+IDSB; Y ; Yes ; T ; True
+
+# IDS_Trinary_Operator (IDST)
+
+IDST; N ; No ; F ; False
+IDST; Y ; Yes ; T ; True
+
+# ID_Continue (IDC)
+
+IDC; N ; No ; F ; False
+IDC; Y ; Yes ; T ; True
+
+# ID_Start (IDS)
+
+IDS; N ; No ; F ; False
+IDS; Y ; Yes ; T ; True
+
+# ISO_Comment (isc)
+
+# @missing: 0000..10FFFF; ISO_Comment; <none>
+
+# Ideographic (Ideo)
+
+Ideo; N ; No ; F ; False
+Ideo; Y ; Yes ; T ; True
+
+# Jamo_Short_Name (JSN)
+
+# @missing: 0000..10FFFF; Jamo_Short_Name; <none>
+JSN; A ; A
+JSN; AE ; AE
+JSN; B ; B
+JSN; BB ; BB
+JSN; BS ; BS
+JSN; C ; C
+JSN; D ; D
+JSN; DD ; DD
+JSN; E ; E
+JSN; EO ; EO
+JSN; EU ; EU
+JSN; G ; G
+JSN; GG ; GG
+JSN; GS ; GS
+JSN; H ; H
+JSN; I ; I
+JSN; J ; J
+JSN; JJ ; JJ
+JSN; K ; K
+JSN; L ; L
+JSN; LB ; LB
+JSN; LG ; LG
+JSN; LH ; LH
+JSN; LM ; LM
+JSN; LP ; LP
+JSN; LS ; LS
+JSN; LT ; LT
+JSN; M ; M
+JSN; N ; N
+JSN; NG ; NG
+JSN; NH ; NH
+JSN; NJ ; NJ
+JSN; O ; O
+JSN; OE ; OE
+JSN; P ; P
+JSN; R ; R
+JSN; S ; S
+JSN; SS ; SS
+JSN; T ; T
+JSN; U ; U
+JSN; WA ; WA
+JSN; WAE ; WAE
+JSN; WE ; WE
+JSN; WEO ; WEO
+JSN; WI ; WI
+JSN; YA ; YA
+JSN; YAE ; YAE
+JSN; YE ; YE
+JSN; YEO ; YEO
+JSN; YI ; YI
+JSN; YO ; YO
+JSN; YU ; YU
+
+# Join_Control (Join_C)
+
+Join_C; N ; No ; F ; False
+Join_C; Y ; Yes ; T ; True
+
+# Joining_Group (jg)
+
+jg ; n/a ; Ain
+jg ; n/a ; Alaph
+jg ; n/a ; Alef
+jg ; n/a ; Beh
+jg ; n/a ; Beth
+jg ; n/a ; Burushaski_Yeh_Barree
+jg ; n/a ; Dal
+jg ; n/a ; Dalath_Rish
+jg ; n/a ; E
+jg ; n/a ; Farsi_Yeh
+jg ; n/a ; Fe
+jg ; n/a ; Feh
+jg ; n/a ; Final_Semkath
+jg ; n/a ; Gaf
+jg ; n/a ; Gamal
+jg ; n/a ; Hah
+jg ; n/a ; He
+jg ; n/a ; Heh
+jg ; n/a ; Heh_Goal
+jg ; n/a ; Heth
+jg ; n/a ; Kaf
+jg ; n/a ; Kaph
+jg ; n/a ; Khaph
+jg ; n/a ; Knotted_Heh
+jg ; n/a ; Lam
+jg ; n/a ; Lamadh
+jg ; n/a ; Meem
+jg ; n/a ; Mim
+jg ; n/a ; No_Joining_Group
+jg ; n/a ; Noon
+jg ; n/a ; Nun
+jg ; n/a ; Nya
+jg ; n/a ; Pe
+jg ; n/a ; Qaf
+jg ; n/a ; Qaph
+jg ; n/a ; Reh
+jg ; n/a ; Reversed_Pe
+jg ; n/a ; Sad
+jg ; n/a ; Sadhe
+jg ; n/a ; Seen
+jg ; n/a ; Semkath
+jg ; n/a ; Shin
+jg ; n/a ; Swash_Kaf
+jg ; n/a ; Syriac_Waw
+jg ; n/a ; Tah
+jg ; n/a ; Taw
+jg ; n/a ; Teh_Marbuta
+jg ; n/a ; Teh_Marbuta_Goal ; Hamza_On_Heh_Goal
+jg ; n/a ; Teth
+jg ; n/a ; Waw
+jg ; n/a ; Yeh
+jg ; n/a ; Yeh_Barree
+jg ; n/a ; Yeh_With_Tail
+jg ; n/a ; Yudh
+jg ; n/a ; Yudh_He
+jg ; n/a ; Zain
+jg ; n/a ; Zhain
+
+# Joining_Type (jt)
+
+jt ; C ; Join_Causing
+jt ; D ; Dual_Joining
+jt ; L ; Left_Joining
+jt ; R ; Right_Joining
+jt ; T ; Transparent
+jt ; U ; Non_Joining
+
+# Line_Break (lb)
+
+lb ; AI ; Ambiguous
+lb ; AL ; Alphabetic
+lb ; B2 ; Break_Both
+lb ; BA ; Break_After
+lb ; BB ; Break_Before
+lb ; BK ; Mandatory_Break
+lb ; CB ; Contingent_Break
+lb ; CL ; Close_Punctuation
+lb ; CM ; Combining_Mark
+lb ; CP ; Close_Parenthesis
+lb ; CR ; Carriage_Return
+lb ; EX ; Exclamation
+lb ; GL ; Glue
+lb ; H2 ; H2
+lb ; H3 ; H3
+lb ; HY ; Hyphen
+lb ; ID ; Ideographic
+lb ; IN ; Inseparable ; Inseperable
+lb ; IS ; Infix_Numeric
+lb ; JL ; JL
+lb ; JT ; JT
+lb ; JV ; JV
+lb ; LF ; Line_Feed
+lb ; NL ; Next_Line
+lb ; NS ; Nonstarter
+lb ; NU ; Numeric
+lb ; OP ; Open_Punctuation
+lb ; PO ; Postfix_Numeric
+lb ; PR ; Prefix_Numeric
+lb ; QU ; Quotation
+lb ; SA ; Complex_Context
+lb ; SG ; Surrogate
+lb ; SP ; Space
+lb ; SY ; Break_Symbols
+lb ; WJ ; Word_Joiner
+lb ; XX ; Unknown
+lb ; ZW ; ZWSpace
+
+# Logical_Order_Exception (LOE)
+
+LOE; N ; No ; F ; False
+LOE; Y ; Yes ; T ; True
+
+# Lowercase (Lower)
+
+Lower; N ; No ; F ; False
+Lower; Y ; Yes ; T ; True
+
+# Lowercase_Mapping (lc)
+
+# @missing: 0000..10FFFF; Lowercase_Mapping; <code point>
+
+# Math (Math)
+
+Math; N ; No ; F ; False
+Math; Y ; Yes ; T ; True
+
+# NFC_Quick_Check (NFC_QC)
+
+NFC_QC; M ; Maybe
+NFC_QC; N ; No
+NFC_QC; Y ; Yes
+
+# NFD_Quick_Check (NFD_QC)
+
+NFD_QC; N ; No
+NFD_QC; Y ; Yes
+
+# NFKC_Casefold (NFKC_CF)
+
+# @missing: 0000..10FFFF; NFKC_Casefold; <code point>
+
+# NFKC_Quick_Check (NFKC_QC)
+
+NFKC_QC; M ; Maybe
+NFKC_QC; N ; No
+NFKC_QC; Y ; Yes
+
+# NFKD_Quick_Check (NFKD_QC)
+
+NFKD_QC; N ; No
+NFKD_QC; Y ; Yes
+
+# Name (na)
+
+# @missing: 0000..10FFFF; Name; <none>
+
+# Name_Alias (Name_Alias)
+
+# @missing: 0000..10FFFF; Name_Alias; <none>
+
+# Noncharacter_Code_Point (NChar)
+
+NChar; N ; No ; F ; False
+NChar; Y ; Yes ; T ; True
+
+# Numeric_Type (nt)
+
+nt ; De ; Decimal
+nt ; Di ; Digit
+nt ; None ; None
+nt ; Nu ; Numeric
+
+# Numeric_Value (nv)
+
+# @missing: 0000..10FFFF; Numeric_Value; NaN
+
+# Other_Alphabetic (OAlpha)
+
+OAlpha; N ; No ; F ; False
+OAlpha; Y ; Yes ; T ; True
+
+# Other_Default_Ignorable_Code_Point (ODI)
+
+ODI; N ; No ; F ; False
+ODI; Y ; Yes ; T ; True
+
+# Other_Grapheme_Extend (OGr_Ext)
+
+OGr_Ext; N ; No ; F ; False
+OGr_Ext; Y ; Yes ; T ; True
+
+# Other_ID_Continue (OIDC)
+
+OIDC; N ; No ; F ; False
+OIDC; Y ; Yes ; T ; True
+
+# Other_ID_Start (OIDS)
+
+OIDS; N ; No ; F ; False
+OIDS; Y ; Yes ; T ; True
+
+# Other_Lowercase (OLower)
+
+OLower; N ; No ; F ; False
+OLower; Y ; Yes ; T ; True
+
+# Other_Math (OMath)
+
+OMath; N ; No ; F ; False
+OMath; Y ; Yes ; T ; True
+
+# Other_Uppercase (OUpper)
+
+OUpper; N ; No ; F ; False
+OUpper; Y ; Yes ; T ; True
+
+# Pattern_Syntax (Pat_Syn)
+
+Pat_Syn; N ; No ; F ; False
+Pat_Syn; Y ; Yes ; T ; True
+
+# Pattern_White_Space (Pat_WS)
+
+Pat_WS; N ; No ; F ; False
+Pat_WS; Y ; Yes ; T ; True
+
+# Quotation_Mark (QMark)
+
+QMark; N ; No ; F ; False
+QMark; Y ; Yes ; T ; True
+
+# Radical (Radical)
+
+Radical; N ; No ; F ; False
+Radical; Y ; Yes ; T ; True
+
+# STerm (STerm)
+
+STerm; N ; No ; F ; False
+STerm; Y ; Yes ; T ; True
+
+# Script (sc)
+
+sc ; Arab ; Arabic
+sc ; Armi ; Imperial_Aramaic
+sc ; Armn ; Armenian
+sc ; Avst ; Avestan
+sc ; Bali ; Balinese
+sc ; Bamu ; Bamum
+sc ; Batk ; Batak
+sc ; Beng ; Bengali
+sc ; Bopo ; Bopomofo
+sc ; Brah ; Brahmi
+sc ; Brai ; Braille
+sc ; Bugi ; Buginese
+sc ; Buhd ; Buhid
+sc ; Cans ; Canadian_Aboriginal
+sc ; Cari ; Carian
+sc ; Cham ; Cham
+sc ; Cher ; Cherokee
+sc ; Copt ; Coptic ; Qaac
+sc ; Cprt ; Cypriot
+sc ; Cyrl ; Cyrillic
+sc ; Deva ; Devanagari
+sc ; Dsrt ; Deseret
+sc ; Egyp ; Egyptian_Hieroglyphs
+sc ; Ethi ; Ethiopic
+sc ; Geor ; Georgian
+sc ; Glag ; Glagolitic
+sc ; Goth ; Gothic
+sc ; Grek ; Greek
+sc ; Gujr ; Gujarati
+sc ; Guru ; Gurmukhi
+sc ; Hang ; Hangul
+sc ; Hani ; Han
+sc ; Hano ; Hanunoo
+sc ; Hebr ; Hebrew
+sc ; Hira ; Hiragana
+sc ; Hrkt ; Katakana_Or_Hiragana
+sc ; Ital ; Old_Italic
+sc ; Java ; Javanese
+sc ; Kali ; Kayah_Li
+sc ; Kana ; Katakana
+sc ; Khar ; Kharoshthi
+sc ; Khmr ; Khmer
+sc ; Knda ; Kannada
+sc ; Kthi ; Kaithi
+sc ; Lana ; Tai_Tham
+sc ; Laoo ; Lao
+sc ; Latn ; Latin
+sc ; Lepc ; Lepcha
+sc ; Limb ; Limbu
+sc ; Linb ; Linear_B
+sc ; Lisu ; Lisu
+sc ; Lyci ; Lycian
+sc ; Lydi ; Lydian
+sc ; Mand ; Mandaic
+sc ; Mlym ; Malayalam
+sc ; Mong ; Mongolian
+sc ; Mtei ; Meetei_Mayek
+sc ; Mymr ; Myanmar
+sc ; Nkoo ; Nko
+sc ; Ogam ; Ogham
+sc ; Olck ; Ol_Chiki
+sc ; Orkh ; Old_Turkic
+sc ; Orya ; Oriya
+sc ; Osma ; Osmanya
+sc ; Phag ; Phags_Pa
+sc ; Phli ; Inscriptional_Pahlavi
+sc ; Phnx ; Phoenician
+sc ; Prti ; Inscriptional_Parthian
+sc ; Rjng ; Rejang
+sc ; Runr ; Runic
+sc ; Samr ; Samaritan
+sc ; Sarb ; Old_South_Arabian
+sc ; Saur ; Saurashtra
+sc ; Shaw ; Shavian
+sc ; Sinh ; Sinhala
+sc ; Sund ; Sundanese
+sc ; Sylo ; Syloti_Nagri
+sc ; Syrc ; Syriac
+sc ; Tagb ; Tagbanwa
+sc ; Tale ; Tai_Le
+sc ; Talu ; New_Tai_Lue
+sc ; Taml ; Tamil
+sc ; Tavt ; Tai_Viet
+sc ; Telu ; Telugu
+sc ; Tfng ; Tifinagh
+sc ; Tglg ; Tagalog
+sc ; Thaa ; Thaana
+sc ; Thai ; Thai
+sc ; Tibt ; Tibetan
+sc ; Ugar ; Ugaritic
+sc ; Vaii ; Vai
+sc ; Xpeo ; Old_Persian
+sc ; Xsux ; Cuneiform
+sc ; Yiii ; Yi
+sc ; Zinh ; Inherited ; Qaai
+sc ; Zyyy ; Common
+sc ; Zzzz ; Unknown
+
+# Sentence_Break (SB)
+
+SB ; AT ; ATerm
+SB ; CL ; Close
+SB ; CR ; CR
+SB ; EX ; Extend
+SB ; FO ; Format
+SB ; LE ; OLetter
+SB ; LF ; LF
+SB ; LO ; Lower
+SB ; NU ; Numeric
+SB ; SC ; SContinue
+SB ; SE ; Sep
+SB ; SP ; Sp
+SB ; ST ; STerm
+SB ; UP ; Upper
+SB ; XX ; Other
+
+# Simple_Case_Folding (scf)
+
+# @missing: 0000..10FFFF; Simple_Case_Folding; <code point>
+
+# Simple_Lowercase_Mapping (slc)
+
+# @missing: 0000..10FFFF; Simple_Lowercase_Mapping; <code point>
+
+# Simple_Titlecase_Mapping (stc)
+
+# @missing: 0000..10FFFF; Simple_Titlecase_Mapping; <code point>
+
+# Simple_Uppercase_Mapping (suc)
+
+# @missing: 0000..10FFFF; Simple_Uppercase_Mapping; <code point>
+
+# Soft_Dotted (SD)
+
+SD ; N ; No ; F ; False
+SD ; Y ; Yes ; T ; True
+
+# Terminal_Punctuation (Term)
+
+Term; N ; No ; F ; False
+Term; Y ; Yes ; T ; True
+
+# Titlecase_Mapping (tc)
+
+# @missing: 0000..10FFFF; Titlecase_Mapping; <code point>
+
+# Unicode_1_Name (na1)
+
+# @missing: 0000..10FFFF; Unicode_1_Name; <none>
+
+# Unified_Ideograph (UIdeo)
+
+UIdeo; N ; No ; F ; False
+UIdeo; Y ; Yes ; T ; True
+
+# Uppercase (Upper)
+
+Upper; N ; No ; F ; False
+Upper; Y ; Yes ; T ; True
+
+# Uppercase_Mapping (uc)
+
+# @missing: 0000..10FFFF; Uppercase_Mapping; <code point>
+
+# Variation_Selector (VS)
+
+VS ; N ; No ; F ; False
+VS ; Y ; Yes ; T ; True
+
+# White_Space (WSpace)
+
+WSpace; N ; No ; F ; False
+WSpace; Y ; Yes ; T ; True
+
+# Word_Break (WB)
+
+WB ; CR ; CR
+WB ; EX ; ExtendNumLet
+WB ; Extend ; Extend
+WB ; FO ; Format
+WB ; KA ; Katakana
+WB ; LE ; ALetter
+WB ; LF ; LF
+WB ; MB ; MidNumLet
+WB ; ML ; MidLetter
+WB ; MN ; MidNum
+WB ; NL ; Newline
+WB ; NU ; Numeric
+WB ; XX ; Other
+
+# XID_Continue (XIDC)
+
+XIDC; N ; No ; F ; False
+XIDC; Y ; Yes ; T ; True
+
+# XID_Start (XIDS)
+
+XIDS; N ; No ; F ; False
+XIDS; Y ; Yes ; T ; True
+
+# cjkAccountingNumeric (cjkAccountingNumeric)
+
+# @missing: 0000..10FFFF; cjkAccountingNumeric; NaN
+
+# cjkCompatibilityVariant (cjkCompatibilityVariant)
+
+# @missing: 0000..10FFFF; cjkCompatibilityVariant; <code point>
+
+# cjkIICore (cjkIICore)
+
+# @missing: 0000..10FFFF; cjkIICore; <none>
+
+# cjkIRG_GSource (cjkIRG_GSource)
+
+# @missing: 0000..10FFFF; cjkIRG_GSource; <none>
+
+# cjkIRG_HSource (cjkIRG_HSource)
+
+# @missing: 0000..10FFFF; cjkIRG_HSource; <none>
+
+# cjkIRG_JSource (cjkIRG_JSource)
+
+# @missing: 0000..10FFFF; cjkIRG_JSource; <none>
+
+# cjkIRG_KPSource (cjkIRG_KPSource)
+
+# @missing: 0000..10FFFF; cjkIRG_KPSource; <none>
+
+# cjkIRG_KSource (cjkIRG_KSource)
+
+# @missing: 0000..10FFFF; cjkIRG_KSource; <none>
+
+# cjkIRG_MSource (cjkIRG_MSource)
+
+# @missing: 0000..10FFFF; cjkIRG_MSource; <none>
+
+# cjkIRG_TSource (cjkIRG_TSource)
+
+# @missing: 0000..10FFFF; cjkIRG_TSource; <none>
+
+# cjkIRG_USource (cjkIRG_USource)
+
+# @missing: 0000..10FFFF; cjkIRG_USource; <none>
+
+# cjkIRG_VSource (cjkIRG_VSource)
+
+# @missing: 0000..10FFFF; cjkIRG_VSource; <none>
+
+# cjkOtherNumeric (cjkOtherNumeric)
+
+# @missing: 0000..10FFFF; cjkOtherNumeric; NaN
+
+# cjkPrimaryNumeric (cjkPrimaryNumeric)
+
+# @missing: 0000..10FFFF; cjkPrimaryNumeric; NaN
+
+# cjkRSUnicode (cjkRSUnicode)
+
+# @missing: 0000..10FFFF; cjkRSUnicode; <none>
+
+# EOF
--- a/jdk/test/java/nio/file/Files/CheckPermissions.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java Tue Apr 12 14:23:03 2011 -0700
@@ -521,19 +521,19 @@
// -- toRealPath --
prepare();
- file.toRealPath(true);
+ file.toRealPath();
assertCheckRead(file);
prepare();
- file.toRealPath(false);
+ file.toRealPath(LinkOption.NOFOLLOW_LINKS);
assertCheckRead(file);
prepare();
- Paths.get(".").toRealPath(true);
+ Paths.get(".").toRealPath();
assertCheckPropertyAccess("user.dir");
prepare();
- Paths.get(".").toRealPath(false);
+ Paths.get(".").toRealPath(LinkOption.NOFOLLOW_LINKS);
assertCheckPropertyAccess("user.dir");
// -- register --
--- a/jdk/test/java/nio/file/Files/PassThroughFileSystem.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/nio/file/Files/PassThroughFileSystem.java Tue Apr 12 14:23:03 2011 -0700
@@ -486,8 +486,8 @@
}
@Override
- public Path toRealPath(boolean resolveLinks) throws IOException {
- return wrap(delegate.toRealPath(resolveLinks));
+ public Path toRealPath(LinkOption... options) throws IOException {
+ return wrap(delegate.toRealPath(options));
}
@Override
--- a/jdk/test/java/nio/file/Path/Misc.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/nio/file/Path/Misc.java Tue Apr 12 14:23:03 2011 -0700
@@ -22,12 +22,13 @@
*/
/* @test
- * @bug 4313887 6838333
+ * @bug 4313887 6838333 7029979
* @summary Unit test for miscellenous java.nio.file.Path methods
* @library ..
*/
import java.nio.file.*;
+import static java.nio.file.LinkOption.*;
import java.io.*;
public class Misc {
@@ -96,65 +97,65 @@
final Path link = dir.resolve("link");
/**
- * Test: totRealPath(true) will access same file as toRealPath(false)
+ * Test: totRealPath() will access same file as toRealPath(NOFOLLOW_LINKS)
*/
- assertTrue(Files.isSameFile(file.toRealPath(true), file.toRealPath(false)));
+ assertTrue(Files.isSameFile(file.toRealPath(), file.toRealPath(NOFOLLOW_LINKS)));
/**
* Test: toRealPath should fail if file does not exist
*/
Path doesNotExist = dir.resolve("DoesNotExist");
try {
- doesNotExist.toRealPath(true);
+ doesNotExist.toRealPath();
throw new RuntimeException("IOException expected");
} catch (IOException expected) {
}
try {
- doesNotExist.toRealPath(false);
+ doesNotExist.toRealPath(NOFOLLOW_LINKS);
throw new RuntimeException("IOException expected");
} catch (IOException expected) {
}
/**
- * Test: toRealPath(true) should resolve links
+ * Test: toRealPath() should resolve links
*/
if (supportsLinks) {
Files.createSymbolicLink(link, file.toAbsolutePath());
- assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
+ assertTrue(link.toRealPath().equals(file.toRealPath()));
Files.delete(link);
}
/**
- * Test: toRealPath(false) should not resolve links
+ * Test: toRealPath(NOFOLLOW_LINKS) should not resolve links
*/
if (supportsLinks) {
Files.createSymbolicLink(link, file.toAbsolutePath());
- assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ assertTrue(link.toRealPath(NOFOLLOW_LINKS).getFileName().equals(link.getFileName()));
Files.delete(link);
}
/**
- * Test: toRealPath(false) with broken link
+ * Test: toRealPath(NOFOLLOW_LINKS) with broken link
*/
if (supportsLinks) {
Path broken = Files.createSymbolicLink(link, doesNotExist);
- assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
+ assertTrue(link.toRealPath(NOFOLLOW_LINKS).getFileName().equals(link.getFileName()));
Files.delete(link);
}
/**
* Test: toRealPath should eliminate "."
*/
- assertTrue(dir.resolve(".").toRealPath(true).equals(dir.toRealPath(true)));
- assertTrue(dir.resolve(".").toRealPath(false).equals(dir.toRealPath(false)));
+ assertTrue(dir.resolve(".").toRealPath().equals(dir.toRealPath()));
+ assertTrue(dir.resolve(".").toRealPath(NOFOLLOW_LINKS).equals(dir.toRealPath(NOFOLLOW_LINKS)));
/**
* Test: toRealPath should eliminate ".." when it doesn't follow a
* symbolic link
*/
Path subdir = Files.createDirectory(dir.resolve("subdir"));
- assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
- assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
+ assertTrue(subdir.resolve("..").toRealPath().equals(dir.toRealPath()));
+ assertTrue(subdir.resolve("..").toRealPath(NOFOLLOW_LINKS).equals(dir.toRealPath(NOFOLLOW_LINKS)));
Files.delete(subdir);
// clean-up
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/EnumMap/DistinctEntrySetElements.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary Sets from Map.entrySet() return distinct objects for each Entry
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class DistinctEntrySetElements {
+ static enum TestEnum { e00, e01, e02 }
+
+ public static void main(String[] args) throws Exception {
+ final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
+
+ for (TestEnum e : TestEnum.values()) {
+ enumMap.put(e, e.name());
+ }
+
+ Set<Map.Entry<TestEnum, String>> entrySet = enumMap.entrySet();
+ HashSet<Map.Entry<TestEnum, String>> hashSet = new HashSet<>(entrySet);
+
+ if (false == hashSet.equals(entrySet)) {
+ throw new RuntimeException("Test FAILED: Sets are not equal.");
+ }
+ if (hashSet.hashCode() != entrySet.hashCode()) {
+ throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/EnumMap/EntrySetIteratorRemoveInvalidatesEntry.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary Iterator.remove() from Map.entrySet().iterator() invalidates returned Entry.
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class EntrySetIteratorRemoveInvalidatesEntry {
+ static enum TestEnum { e00, e01, e02 }
+
+ public static void main(String[] args) throws Exception {
+ final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
+
+ for (TestEnum e : TestEnum.values()) {
+ enumMap.put(e, e.name());
+ }
+
+ Iterator<Map.Entry<TestEnum, String>> entrySetIterator =
+ enumMap.entrySet().iterator();
+ Map.Entry<TestEnum, String> entry = entrySetIterator.next();
+
+ entrySetIterator.remove();
+
+ try {
+ entry.getKey();
+ throw new RuntimeException("Test FAILED: Entry not invalidated by removal.");
+ } catch (Exception e) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/EnumMap/SimpleSerialization.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary A serialized EnumMap can be successfully de-serialized.
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.EnumMap;
+
+public class SimpleSerialization {
+ private enum TestEnum { e00, e01, e02, e03, e04, e05, e06, e07 }
+ public static void main(final String[] args) throws Exception {
+ final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
+
+ enumMap.put(TestEnum.e01, TestEnum.e01.name());
+ enumMap.put(TestEnum.e04, TestEnum.e04.name());
+ enumMap.put(TestEnum.e05, TestEnum.e05.name());
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ oos.writeObject(enumMap);
+ oos.close();
+
+ final byte[] data = baos.toByteArray();
+ final ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ final ObjectInputStream ois = new ObjectInputStream(bais);
+
+ final Object deserializedObject = ois.readObject();
+ ois.close();
+
+ if (false == enumMap.equals(deserializedObject)) {
+ throw new RuntimeException(getFailureText(enumMap, deserializedObject));
+ }
+ }
+
+ private static String getFailureText(final Object orig, final Object copy) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+
+ pw.println("Test FAILED: Deserialized object is not equal to the original object");
+ pw.print("\tOriginal: ");
+ printObject(pw, orig).println();
+ pw.print("\tCopy: ");
+ printObject(pw, copy).println();
+
+ pw.close();
+ return sw.toString();
+ }
+
+ private static PrintWriter printObject(final PrintWriter pw, final Object o) {
+ pw.printf("%s@%08x", o.getClass().getName(), System.identityHashCode(o));
+ return pw;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/IdentityHashMap/DistinctEntrySetElements.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary Sets from Map.entrySet() return distinct objects for each Entry
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.util.IdentityHashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class DistinctEntrySetElements {
+ public static void main(String[] args) throws Exception {
+ final IdentityHashMap<String, String> identityHashMap =
+ new IdentityHashMap<>();
+
+ identityHashMap.put("One", "Un");
+ identityHashMap.put("Two", "Deux");
+ identityHashMap.put("Three", "Trois");
+
+ Set<Map.Entry<String, String>> entrySet = identityHashMap.entrySet();
+ HashSet<Map.Entry<String, String>> hashSet = new HashSet<>(entrySet);
+
+ // NB: These comparisons are valid in this case because none of the
+ // keys put into 'identityHashMap' above are equal to any other.
+ if (false == hashSet.equals(entrySet)) {
+ throw new RuntimeException("Test FAILED: Sets are not equal.");
+ }
+ if (hashSet.hashCode() != entrySet.hashCode()) {
+ throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/IdentityHashMap/EntrySetIteratorRemoveInvalidatesEntry.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary Iterator.remove() from Map.entrySet().iterator() invalidates returned Entry.
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class EntrySetIteratorRemoveInvalidatesEntry {
+ public static void main(String[] args) throws Exception {
+ final IdentityHashMap<String, String> identityHashMap =
+ new IdentityHashMap<>();
+
+ identityHashMap.put("One", "Un");
+ identityHashMap.put("Two", "Deux");
+ identityHashMap.put("Three", "Trois");
+
+ Iterator<Map.Entry<String, String>> entrySetIterator =
+ identityHashMap.entrySet().iterator();
+ Map.Entry<String, String> entry = entrySetIterator.next();
+
+ entrySetIterator.remove();
+
+ try {
+ entry.getKey();
+ throw new RuntimeException("Test FAILED: Entry not invalidated by removal.");
+ } catch (Exception e) { }
+ }
+}
--- a/jdk/test/java/util/PriorityQueue/NoNulls.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/PriorityQueue/NoNulls.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Martin Buchholz with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/Random/DistinctSeeds.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/Random/DistinctSeeds.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/ResourceBundle/Bug4168625Test.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/ResourceBundle/Bug4168625Test.java Tue Apr 12 14:23:03 2011 -0700
@@ -282,7 +282,7 @@
thread1.start(); //start thread 1
loader.waitForNotify(1); //wait for thread1 to do getBundle & block in loader
thread2.start(); //start second thread
- thread2.join(1000); //wait until thread2 blocks somewhere in getBundle
+ thread2.join(); //wait until thread2 terminates.
//Thread1 should be blocked inside getBundle at the class loader
//Thread2 should have completed its getBundle call and terminated
@@ -292,7 +292,6 @@
thread1.ping(); //continue thread1
thread1.join();
- thread2.join();
}
/**
@@ -318,8 +317,7 @@
loader.waitForNotify(3); //wait for thread1 to do getBundle(en) & block in loader
causeResourceBundleCacheFlush(); //cause a cache flush
thread1.ping(); //kick thread 1
- thread1.ping(); //kick thread 1
- thread1.join(1000); //wait until thread2 blocks somewhere in getBundle
+ thread1.join(); //wait until thread1 terminates
ResourceBundle bundle = (ResourceBundle)thread1.bundle;
String s1 = bundle.getString("Bug4168625Resource3_en_US");
--- a/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/DistinctEntrySetElements.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6312706
+ * @summary Sets from Map.entrySet() return distinct objects for each Entry
+ * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ */
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class DistinctEntrySetElements {
+ public static void main(String[] args) throws Exception {
+ final ConcurrentHashMap<String, String> concurrentHashMap =
+ new ConcurrentHashMap<>();
+
+ concurrentHashMap.put("One", "Un");
+ concurrentHashMap.put("Two", "Deux");
+ concurrentHashMap.put("Three", "Trois");
+
+ Set<Map.Entry<String, String>> entrySet = concurrentHashMap.entrySet();
+ HashSet<Map.Entry<String, String>> hashSet = new HashSet<>(entrySet);
+
+ if (false == hashSet.equals(entrySet)) {
+ throw new RuntimeException("Test FAILED: Sets are not equal.");
+ }
+ if (hashSet.hashCode() != entrySet.hashCode()) {
+ throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
+ }
+ }
+}
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
* @test
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.*;
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
--- a/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Exchanger/ExchangeLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Exchanger/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Misc utilities in JSR166 performance tests
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Misc utilities in JSR166 performance tests
--- a/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/FutureTask/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Misc utilities in JSR166 performance tests
--- a/jdk/test/java/util/concurrent/Phaser/Arrive.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Phaser/Arrive.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Phaser/Basic.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Phaser/Basic.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Phaser/FickleRegister.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Phaser/PhaseOverflow.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Phaser/PhaseOverflow.java Tue Apr 12 14:23:03 2011 -0700
@@ -29,7 +29,7 @@
* Written by Martin Buchholz and Doug Lea with assistance from
* members of JCP JSR-166 Expert Group and released to the public
* domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Phaser/TieredArriveLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Semaphore/PermitOverflow.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Semaphore/PermitOverflow.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/Semaphore/RacingReleases.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/Semaphore/RacingReleases.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/forkjoin/Integrate.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/forkjoin/Integrate.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/forkjoin/NQueensCS.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/forkjoin/NQueensCS.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Misc utilities in JSR166 performance tests
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Misc utilities in JSR166 performance tests
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
/*
--- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Tue Apr 12 14:23:03 2011 -0700
@@ -28,7 +28,7 @@
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/licenses/publicdomain
+ * http://creativecommons.org/publicdomain/zero/1.0/
*/
import java.util.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/zip/FlaterCriticalArray.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+/**
+ * ZIP inflater/deflater performance.
+ */
+
+/*
+ * Run this test on JDK 6 and on later
+ * JDKs to compare results:
+ * java -server -Xms1024M -Xmx1024M -Ddebug=true FlaterCriticalArray
+ *
+ * The performance issues can be readily seen on JDK 6, and so this code is
+ * written to compile on that platform: it does *not* use any JDK 7 - specific
+ * features.
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class FlaterCriticalArray {
+ // If true, print information about performance
+ private static final boolean debug = System.getProperty("debug") != null;
+
+ private static void debug(String s) {
+ if (debug) System.out.println(s);
+ }
+
+ private static void debug(String name, String inOut, long time, int length) {
+ debug(name + ": Duration of " + inOut + "(in ms): " + time);
+ debug(name + ": " + inOut + "d data length: " + length + " bytes");
+ }
+
+ private static byte[] grow(byte[] a, int capacity) {
+ while (a.length < capacity) {
+ byte[] a2 = new byte[a.length * 2];
+ System.arraycopy(a, 0, a2, 0, a.length);
+ a = a2;
+ }
+ return a;
+ }
+
+ private static byte[] trim(byte[] a, int length) {
+ byte[] res = new byte[length];
+ System.arraycopy(a, 0, res, 0, length);
+ return res;
+ }
+
+ /*
+ * Base class for individual test cases
+ */
+ abstract static private class TestCase {
+ protected String name; // For information in debug messages
+ protected byte data[]; // Data to be deflated and subsequently inflated
+ protected int level; // Compression level for deflater
+
+ protected TestCase(String name, byte data[]) {
+ this(name, data, -1);
+ }
+
+ protected TestCase(String name, byte data[], int level) {
+ this.name = name;
+ this.data = data;
+ this.level = level;
+ }
+
+ public void runTest() throws Throwable {
+ long time0, time1;
+ byte deflated[], inflated[];
+
+ debug("");
+
+ time0 = System.currentTimeMillis();
+ deflated = deflate(data, level);
+ time1 = System.currentTimeMillis();
+ inform("Deflate", time1 - time0, deflated.length);
+
+ time0 = System.currentTimeMillis();
+ inflated = inflate(deflated);
+ time1 = System.currentTimeMillis();
+ inform("Inflate", time1 - time0, inflated.length);
+
+ check(Arrays.equals(data, inflated),
+ name + ": Inflated and deflated arrays do not match");
+ }
+
+ private void inform(String inOut, long duration, int length) {
+ debug(name, inOut, duration, length);
+ }
+
+ abstract protected byte[] deflate(byte data[], int level) throws Throwable;
+
+ abstract protected byte[] inflate(byte deflated[]) throws Throwable;
+ }
+
+ /*
+ * Following are the individual test cases
+ */
+
+ private static class StrideTest extends TestCase {
+ static final int STRIDE = 1024;
+
+ public StrideTest(byte data[], int level) {
+ super("STRIDE", data, level);
+ }
+
+ protected byte[] deflate(byte in[], int level) throws Throwable {
+ final int len = in.length;
+ final Deflater deflater = new Deflater(level);
+ final byte[] smallBuffer = new byte[32];
+ byte[] flated = new byte[32];
+ int count = 0;
+ for (int i = 0; i<len; i+= STRIDE) {
+ deflater.setInput(in, i, Math.min(STRIDE, len-i));
+ while (!deflater.needsInput()) {
+ int n = deflater.deflate(smallBuffer);
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ }
+ deflater.finish();
+ int n;
+ do {
+ n = deflater.deflate(smallBuffer);
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ } while (n > 0);
+ return trim(flated, count);
+ }
+
+ protected byte[] inflate(byte in[]) throws Throwable {
+ final int len = in.length;
+ final Inflater inflater = new Inflater();
+ final byte[] smallBuffer = new byte[3200];
+
+ byte[] flated = new byte[32];
+ int count = 0;
+
+ for (int i = 0; i<len; i+= STRIDE) {
+ inflater.setInput(in, i, Math.min(STRIDE, len-i));
+ while (!inflater.needsInput()) {
+ int n;
+ while ((n = inflater.inflate(smallBuffer)) > 0) {
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ }
+ }
+ return trim(flated, count);
+ }
+ }
+
+ private static class NoStrideTest extends TestCase {
+ public NoStrideTest(byte data[], int level) {
+ super("NO STRIDE", data, level);
+ }
+
+ public byte[] deflate(byte in[], int level) throws Throwable {
+ final Deflater flater = new Deflater(level);
+ flater.setInput(in);
+ flater.finish();
+ final byte[] smallBuffer = new byte[32];
+ byte[] flated = new byte[32];
+ int count = 0;
+ int n;
+ while ((n = flater.deflate(smallBuffer)) > 0) {
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ return trim(flated, count);
+ }
+
+ public byte[] inflate(byte in[]) throws Throwable {
+ final Inflater flater = new Inflater();
+ flater.setInput(in);
+ final byte[] smallBuffer = new byte[32];
+ byte[] flated = new byte[32];
+ int count = 0;
+ int n;
+ while ((n = flater.inflate(smallBuffer)) > 0) {
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ return trim(flated, count);
+ }
+ }
+
+ /**
+ * Check Deflater{In,Out}putStream by way of GZIP{In,Out}putStream
+ */
+ private static class GZIPTest extends TestCase {
+ public GZIPTest(byte data[]) {
+ super("GZIP", data);
+ }
+
+ public byte[] deflate(byte data[], int ignored) throws Throwable {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStream gzos = new GZIPOutputStream(baos);
+ gzos.write(data, 0, data.length);
+ gzos.close();
+ return baos.toByteArray();
+ }
+
+ public byte[] inflate(byte deflated[]) throws Throwable {
+ InputStream bais = new ByteArrayInputStream(deflated);
+ GZIPInputStream gzis = new GZIPInputStream(bais);
+ byte[] inflated = new byte[data.length];
+ int numRead = 0;
+ int count = 0;
+ while ((numRead = gzis.read(inflated, count, data.length - count)) > 0) {
+ count += numRead;
+ }
+ check(count == data.length, name + ": Read " + count + "; expected " + data.length);
+ return inflated;
+ }
+ }
+
+ public static void realMain(String[] args) throws Throwable {
+ byte data[];
+ int level = -1;
+ if (args.length > 0) {
+ level = Integer.parseInt(args[0]);
+ }
+ debug("Using level " + level);
+
+ if (args.length > 1) {
+ FileInputStream fis = new FileInputStream(args[1]);
+ int len = fis.available();
+ data = new byte[len];
+ check(fis.read(data, 0, len) == len, "Did not read complete file");
+ debug("Original data from " + args[1]);
+ fis.close();
+ } else {
+ ByteBuffer bb = ByteBuffer.allocate(8);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ for (int i = 0; i < 1024 * 64; i++) { // data length
+ bb.putDouble(0, Math.random());
+ baos.write(bb.array(), 0, 8);
+ }
+ data = baos.toByteArray();
+ debug("Original data from random byte array");
+ }
+ debug("Original data length: " + data.length + " bytes");
+
+ new StrideTest(data, level).runTest();
+ new NoStrideTest(data, level).runTest();
+ new GZIPTest(data).runTest();
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void pass(String msg) {System.out.println(msg); passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void unexpected(Throwable t, String msg) {
+ System.out.println(msg); failed++; t.printStackTrace();}
+ static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+ static boolean check(boolean cond, String msg) {if (cond) pass(); else fail(msg); return cond;}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.println("\nPassed = " + passed + " failed = " + failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/zip/InflaterBufferSize.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6571338
+ * @summary Inflater should not require a buffer to the inflate() methods
+ * larger than 1 byte.
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class InflaterBufferSize {
+ private static final int DATA_LEN = 1024 *64;
+ private static byte[] data;
+
+ // If true, print extra info.
+ private static final boolean debug = System.getProperty("debug") != null;
+
+ private static void debug(String s) {
+ if (debug) System.out.println(s);
+ }
+
+ private static void createData() {
+ ByteBuffer bb = ByteBuffer.allocate(8);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ for (int i = 0; i < DATA_LEN; i++) {
+ bb.putDouble(0, Math.random());
+ baos.write(bb.array(), 0, 8);
+ }
+ data = baos.toByteArray();
+ }
+
+ private static byte[] grow(byte[] a, int capacity) {
+ while (a.length < capacity) {
+ byte[] a2 = new byte[a.length * 2];
+ System.arraycopy(a, 0, a2, 0, a.length);
+ a = a2;
+ }
+ return a;
+ }
+
+ private static byte[] trim(byte[] a, int length) {
+ byte[] res = new byte[length];
+ System.arraycopy(a, 0, res, 0, length);
+ return res;
+ }
+
+ private static byte[] deflate(byte[] in, int level) throws Throwable {
+ final Deflater flater = new Deflater(level);
+ flater.setInput(in);
+ flater.finish();
+ final byte[] smallBuffer = new byte[32];
+ byte[] flated = new byte[32];
+ int count = 0;
+ int n;
+ while ((n = flater.deflate(smallBuffer)) > 0) {
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ return trim(flated, count);
+ }
+
+ private static byte[] inflate(byte[] in) throws Throwable {
+ final Inflater flater = new Inflater();
+ flater.setInput(in);
+ // This is the buffer of interest. It should be possible to use any
+ // non-zero size.
+ final byte[] smallBuffer = new byte[1];
+ byte[] flated = new byte[32];
+ int count = 0;
+ int n;
+ while ((n = flater.inflate(smallBuffer)) > 0) {
+ flated = grow(flated, count + n);
+ System.arraycopy(smallBuffer, 0, flated, count, n);
+ count += n;
+ }
+ return trim(flated, count);
+ }
+
+ public static void realMain(String[] args) throws Throwable {
+ byte deflated[], inflated[];
+
+ int level = -1;
+ if (args.length > 0) {
+ level = Integer.parseInt(args[0]);
+ }
+ debug("Using level " + level);
+
+ if (args.length > 1) {
+ FileInputStream fis = new FileInputStream(args[1]);
+ int len = fis.available();
+ data = new byte[len];
+ check(fis.read(data, 0, len) == len, "Did not read complete file");
+ debug("Original data from " + args[1]);
+ fis.close();
+ } else {
+ createData();
+ debug("Original data from random byte array");
+ }
+ debug("Original data length: " + data.length + " bytes");
+
+ debug("");
+ deflated = deflate(data, level);
+ debug("Deflated data length: " + deflated.length + " bytes");
+
+ inflated = inflate(deflated);
+ debug("Inflated data length: "+ inflated.length + " bytes" );
+
+ if (!check(Arrays.equals(data, inflated),
+ "Inflated and deflated arrays do not match")) {
+ OutputStream os = new BufferedOutputStream(new FileOutputStream("deflated.zip"));
+ try {
+ os.write(deflated);
+ } finally {
+ os.close();
+ }
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void pass(String msg) {System.out.println(msg); passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void unexpected(Throwable t, String msg) {
+ System.out.println(msg); failed++; t.printStackTrace();}
+ static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+ static boolean check(boolean cond, String msg) {if (cond) pass(); else fail(msg); return cond;}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.println("\nPassed = " + passed + " failed = " + failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sample/chatserver/ChatTest.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/* @test
+ * @summary Test chat server chatserver test
+ *
+ * @library ../../../src/share/sample/nio/chatserver
+ * @build ChatTest ChatServer Client ClientReader DataReader MessageReader NameReader
+ * @run main ChatTest
+ */
+
+import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+
+public class ChatTest {
+ public static int listeningPort = 0;
+
+ public static void main(String[] args) throws Throwable {
+ testStartStop();
+ testPortOpen();
+ testAsksForName();
+ testUseName();
+ testConnectDisconnectConnect();
+ testUsernameAndMessage();
+ testDontReceiveMessageInNameState();
+ }
+
+ private static ChatServer startServer() throws IOException {
+ ChatServer server = new ChatServer(0);
+ InetSocketAddress address = (InetSocketAddress) server.getSocketAddress();
+ listeningPort = address.getPort();
+ server.run();
+ return server;
+ }
+
+ public static void testStartStop() throws Exception {
+ ChatServer server = startServer();
+ server.shutdown();
+ }
+
+ public static void testPortOpen() throws Exception {
+ ChatServer server = startServer();
+ try {
+ Socket socket = new Socket("localhost", listeningPort);
+ if (!socket.isConnected()) {
+ throw new RuntimeException("Failed to connect to server: port not open");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testAsksForName() throws Exception {
+ ChatServer server = startServer();
+ try {
+ Socket socket = new Socket("localhost", listeningPort);
+
+ Reader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ String string = readAvailableString(reader);
+ if (!string.equals("Name: ")) {
+ throw new RuntimeException("Server doesn't send Name: ");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testUseName() throws Throwable {
+ ChatServer server = startServer();
+ try {
+ performTestUseName();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testConnectDisconnectConnect() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performTestConnectDisconnectConnect();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testUsernameAndMessage() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performTestUsernameAndMessage();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public static void testDontReceiveMessageInNameState() throws Exception {
+ ChatServer server = startServer();
+ try {
+ performDontReceiveMessageInNameState();
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ private static void assertEqual(List<Exception> exception, Object value, Object expected) {
+ if (expected == value) {
+ return;
+ }
+ if (expected == null) {
+ exception.add(new RuntimeException("Expected null, but was: " + value));
+ return;
+ }
+ if (!expected.equals(value)) {
+ exception.add(new RuntimeException("Expected: " + expected + " but was: " + value));
+ return;
+ }
+ }
+
+ private static void performDontReceiveMessageInNameState() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ writer.write("Ignore this!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ barrier1.await();
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ string = readAvailableString(reader, true);
+ assertEqual(exceptions, string, null);
+ writer.write("testClient2\n");
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+
+ }
+
+ private static void waitForJoin(BufferedReader reader, String s) throws IOException {
+ String joined;
+ do {
+ joined = readAvailableString(reader);
+ } while (!(joined != null && joined.contains("Welcome " + s)));
+ }
+
+ private static void performTestUsernameAndMessage() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = Collections.synchronizedList(new ArrayList<Exception>());
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ barrier2.await();
+ string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient2: Hello world!\n");
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ barrier1.await();
+ writer.write("testClient2\nHello world!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static void performTestConnectDisconnectConnect() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = new ArrayList<Exception>();
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "Name: ");
+ writer.write("testClient1\n");
+ }
+ };
+
+ ChatConnection chatConnection2 = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ readAvailableString(reader);
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ writer.write("Good morning!\n");
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient2: Hello world!\n");
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ readAvailableString(reader);
+ writer.write("testClient2\n");
+ waitForJoin(reader, "testClient2");
+ barrier1.await();
+ writer.write("Hello world!\n");
+ barrier2.await();
+ String string = readAvailableString(reader);
+ assertEqual(exceptions, string, "testClient1: Good morning!\n");
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ chatConnection2.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static void performTestUseName() throws Exception {
+ final CyclicBarrier barrier1 = new CyclicBarrier(2);
+ final CyclicBarrier barrier2 = new CyclicBarrier(2);
+ final CyclicBarrier barrier3 = new CyclicBarrier(2);
+ final List<Exception> exceptions = new ArrayList<Exception>();
+
+ ChatConnection chatConnection = new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ if (!"Name: ".equals(string)) {
+ exceptions.add(new RuntimeException("Expected Name: "));
+ }
+ writer.write("testClient1\n");
+ waitForJoin(reader, "testClient1");
+ barrier1.await();
+ barrier2.await();
+ string = readAvailableString(reader);
+ if (!"testClient2: Hello world!\n".equals(string)) {
+ exceptions.add(new RuntimeException("testClient2: Hello world!\n"));
+ }
+ barrier3.await();
+ }
+ };
+
+ Thread client2 = new Thread(new ChatConnection() {
+ @Override
+ public void run(Socket socket, BufferedReader reader, Writer writer) throws Exception {
+ String string = readAvailableString(reader);
+ if (!"Name: ".equals(string)) {
+ exceptions.add(new RuntimeException("Expected Name: "));
+ }
+ writer.write("testClient2\n");
+ waitForJoin(reader, "testClient2");
+ barrier1.await();
+ writer.write("Hello world!\n");
+ barrier2.await();
+ barrier3.await();
+ }
+ });
+
+ client2.start();
+ chatConnection.run();
+ if (!exceptions.isEmpty()) {
+ throw exceptions.get(0);
+ }
+ }
+
+ private static String readAvailableString(Reader reader) throws IOException {
+ return readAvailableString(reader, false);
+ }
+
+ private static String readAvailableString(Reader reader, boolean now) throws IOException {
+ StringBuilder builder = new StringBuilder();
+ int bytes;
+ if (now && !reader.ready()) {
+ return null;
+ }
+ do {
+ char[] buf = new char[256];
+ bytes = reader.read(buf);
+ builder.append(buf, 0, bytes);
+ } while (bytes == 256);
+ return builder.toString();
+ }
+
+ private abstract static class ChatConnection implements Runnable {
+ public Exception exception;
+
+ @Override
+ public void run() {
+ try (Socket socket = new Socket("localhost", listeningPort);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ Writer writer = new FlushingWriter(new OutputStreamWriter(socket.getOutputStream()))) {
+ socket.setTcpNoDelay(true);
+
+ run(socket, reader, writer);
+ } catch (Exception e) {
+ exception = e;
+ }
+ }
+
+ public abstract void run(Socket socket, BufferedReader reader, Writer writer) throws Exception;
+ }
+
+ private static class FlushingWriter extends Writer {
+ public final Writer delegate;
+
+ private FlushingWriter(Writer delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ delegate.write(cbuf, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ delegate.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ @Override
+ public void write(String str) throws IOException {
+ super.write(str);
+ flush();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sample/mergesort/MergeSortTest.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/* @test
+ * @summary Test MergeSort
+ *
+ * @library ../../../src/share/sample/forkjoin/mergesort
+ * @build MergeSortTest MergeDemo MergeSort
+ * @run main MergeSortTest
+ */
+
+import java.util.Arrays;
+import java.util.Random;
+
+public class MergeSortTest {
+ private Random random;
+ private MergeSort target;
+
+ public MergeSortTest(Random random, MergeSort target) {
+ this.random = random;
+ this.target = target;
+ }
+
+ public static void main(String[] args) {
+ MergeSortTest test = new MergeSortTest(new Random(), new MergeSort(Runtime.getRuntime().availableProcessors() * 4));
+ test.run();
+ }
+
+ private int[] generateArray(int elements) {
+ int[] array = new int[elements];
+ for (int i = 0; i < array.length; ++i) {
+ array[i] = random.nextInt(10);
+ }
+ return array;
+ }
+
+ private void run() {
+ testSort();
+ testSortSingle();
+ testSortEmpty();
+ testLong();
+ }
+
+ public void testLong() {
+ for (int i = 0; i < 1000; ++i) {
+ int elements = 1 + i * 100;
+
+ int[] array = generateArray(elements);
+ int[] copy = Arrays.copyOf(array, array.length);
+ Arrays.sort(copy);
+ target.sort(array);
+ assertEqual(copy, array);
+ }
+ }
+
+ private void testSortEmpty() {
+ int[] array = { };
+ target.sort(array);
+ assertEqual(new int[] { }, array);
+ }
+
+ private void testSortSingle() {
+ int[] array = { 1 };
+ target.sort(array);
+ assertEqual(new int[] { 1 }, array);
+ }
+
+ private void testSort() {
+ int[] array = { 7, 3, 9, 0, -6, 12, 54, 3, -6, 88, 1412};
+ target.sort(array);
+ assertEqual(new int[] { -6, -6, 0, 3, 3, 7, 9, 12, 54, 88, 1412 }, array);
+ }
+
+ private void assertEqual(int[] expected, int[] array) {
+ if (!Arrays.equals(expected, array)) {
+ throw new RuntimeException("Invalid sorted array!");
+ }
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/KrbCredSubKey.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 7030180
+ * @run main/othervm KrbCredSubKey
+ * @summary AES 128/256 decrypt exception
+ */
+
+import java.io.FileOutputStream;
+import java.security.PrivilegedExceptionAction;
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSManager;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+import sun.security.krb5.EncryptedData;
+
+public class KrbCredSubKey {
+
+ public static void main(String[] args) throws Exception {
+
+ // We don't care about clock difference
+ new FileOutputStream("krb5.conf").write(
+ "[libdefaults]\nclockskew=999999999".getBytes());
+ System.setProperty("java.security.krb5.conf", "krb5.conf");
+ Config.refresh();
+
+ Subject subj = new Subject();
+ KerberosPrincipal kp = new KerberosPrincipal(princ);
+ KerberosKey kk = new KerberosKey(
+ kp, key, EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, 0);
+ subj.getPrincipals().add(kp);
+ subj.getPrivateCredentials().add(kk);
+
+ Subject.doAs(subj, new PrivilegedExceptionAction() {
+ public Object run() throws Exception {
+ GSSManager man = GSSManager.getInstance();
+ GSSContext ctxt = man.createContext(man.createCredential(
+ null, GSSCredential.INDEFINITE_LIFETIME,
+ GSSUtil.GSS_KRB5_MECH_OID, GSSCredential.ACCEPT_ONLY));
+ return ctxt.acceptSecContext(token, 0, token.length);
+ }
+ });
+ }
+
+ // All following data generated by myself on a test machine
+
+ private static String princ = "server/host.rabbit.hole@RABBIT.HOLE";
+
+ // A aes-128 key for princ
+ private static byte[] key = {
+ (byte)0x83, (byte)0xA1, (byte)0xD6, (byte)0xE2,
+ (byte)0xC7, (byte)0x76, (byte)0xD5, (byte)0x24,
+ (byte)0x63, (byte)0x9F, (byte)0xF9, (byte)0xFF,
+ (byte)0x76, (byte)0x6D, (byte)0x26, (byte)0x30,
+ };
+
+ // A JGSS token generated by the first call of an initiator's
+ // initSecContext, targetting princ, using the authenticator
+ // subkey to encrypt the KRB_CRED inside AP_REQ
+ private static byte[] token = {
+ (byte)0x60, (byte)0x82, (byte)0x04, (byte)0x1C,
+ (byte)0x06, (byte)0x09, (byte)0x2A, (byte)0x86,
+ (byte)0x48, (byte)0x86, (byte)0xF7, (byte)0x12,
+ (byte)0x01, (byte)0x02, (byte)0x02, (byte)0x01,
+ (byte)0x00, (byte)0x6E, (byte)0x82, (byte)0x04,
+ (byte)0x0B, (byte)0x30, (byte)0x82, (byte)0x04,
+ (byte)0x07, (byte)0xA0, (byte)0x03, (byte)0x02,
+ (byte)0x01, (byte)0x05, (byte)0xA1, (byte)0x03,
+ (byte)0x02, (byte)0x01, (byte)0x0E, (byte)0xA2,
+ (byte)0x07, (byte)0x03, (byte)0x05, (byte)0x00,
+ (byte)0x20, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0xA3, (byte)0x82, (byte)0x01, (byte)0x04,
+ (byte)0x61, (byte)0x82, (byte)0x01, (byte)0x00,
+ (byte)0x30, (byte)0x81, (byte)0xFD, (byte)0xA0,
+ (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x05,
+ (byte)0xA1, (byte)0x0D, (byte)0x1B, (byte)0x0B,
+ (byte)0x52, (byte)0x41, (byte)0x42, (byte)0x42,
+ (byte)0x49, (byte)0x54, (byte)0x2E, (byte)0x48,
+ (byte)0x4F, (byte)0x4C, (byte)0x45, (byte)0xA2,
+ (byte)0x25, (byte)0x30, (byte)0x23, (byte)0xA0,
+ (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00,
+ (byte)0xA1, (byte)0x1C, (byte)0x30, (byte)0x1A,
+ (byte)0x1B, (byte)0x06, (byte)0x73, (byte)0x65,
+ (byte)0x72, (byte)0x76, (byte)0x65, (byte)0x72,
+ (byte)0x1B, (byte)0x10, (byte)0x68, (byte)0x6F,
+ (byte)0x73, (byte)0x74, (byte)0x2E, (byte)0x72,
+ (byte)0x61, (byte)0x62, (byte)0x62, (byte)0x69,
+ (byte)0x74, (byte)0x2E, (byte)0x68, (byte)0x6F,
+ (byte)0x6C, (byte)0x65, (byte)0xA3, (byte)0x81,
+ (byte)0xBF, (byte)0x30, (byte)0x81, (byte)0xBC,
+ (byte)0xA0, (byte)0x03, (byte)0x02, (byte)0x01,
+ (byte)0x11, (byte)0xA2, (byte)0x81, (byte)0xB4,
+ (byte)0x04, (byte)0x81, (byte)0xB1, (byte)0xA7,
+ (byte)0xE8, (byte)0x58, (byte)0xBA, (byte)0x98,
+ (byte)0x69, (byte)0x45, (byte)0xB3, (byte)0x68,
+ (byte)0xBF, (byte)0xFD, (byte)0x25, (byte)0x74,
+ (byte)0xC4, (byte)0x2E, (byte)0x09, (byte)0x7B,
+ (byte)0x3C, (byte)0x7F, (byte)0xA5, (byte)0x6C,
+ (byte)0xC3, (byte)0x86, (byte)0xC9, (byte)0xEE,
+ (byte)0x58, (byte)0xD3, (byte)0x7C, (byte)0xD6,
+ (byte)0x19, (byte)0xA1, (byte)0x3B, (byte)0xF7,
+ (byte)0x17, (byte)0xD6, (byte)0x18, (byte)0xA9,
+ (byte)0x58, (byte)0x43, (byte)0x55, (byte)0xD6,
+ (byte)0xBA, (byte)0x85, (byte)0xF7, (byte)0x6B,
+ (byte)0x20, (byte)0x01, (byte)0xEF, (byte)0xB4,
+ (byte)0x74, (byte)0x0B, (byte)0x31, (byte)0x07,
+ (byte)0x55, (byte)0xD8, (byte)0x8C, (byte)0x85,
+ (byte)0x25, (byte)0x12, (byte)0x66, (byte)0x85,
+ (byte)0xA8, (byte)0x5A, (byte)0x84, (byte)0xB2,
+ (byte)0x6C, (byte)0xDE, (byte)0xEE, (byte)0xF9,
+ (byte)0x15, (byte)0xF2, (byte)0xBC, (byte)0xB0,
+ (byte)0x43, (byte)0xA5, (byte)0x21, (byte)0x31,
+ (byte)0xFA, (byte)0x2F, (byte)0x2C, (byte)0x37,
+ (byte)0x39, (byte)0xD8, (byte)0xAA, (byte)0xE0,
+ (byte)0x78, (byte)0x08, (byte)0x18, (byte)0xFB,
+ (byte)0x03, (byte)0x43, (byte)0x22, (byte)0xE6,
+ (byte)0x2C, (byte)0xF2, (byte)0x98, (byte)0xDC,
+ (byte)0x2A, (byte)0xDE, (byte)0x8C, (byte)0x95,
+ (byte)0x0B, (byte)0xB6, (byte)0xE6, (byte)0x0F,
+ (byte)0xB5, (byte)0x4E, (byte)0xAD, (byte)0xAC,
+ (byte)0xD1, (byte)0x4C, (byte)0xE8, (byte)0x22,
+ (byte)0x93, (byte)0x38, (byte)0xA2, (byte)0x44,
+ (byte)0x0E, (byte)0x83, (byte)0x9E, (byte)0x4D,
+ (byte)0xC0, (byte)0x1A, (byte)0x02, (byte)0xB2,
+ (byte)0xB8, (byte)0xCE, (byte)0xDF, (byte)0xB5,
+ (byte)0xFB, (byte)0xF2, (byte)0x75, (byte)0x5E,
+ (byte)0x74, (byte)0xC1, (byte)0x90, (byte)0x82,
+ (byte)0x60, (byte)0x00, (byte)0xA5, (byte)0xC3,
+ (byte)0xBF, (byte)0x66, (byte)0x97, (byte)0x0E,
+ (byte)0xF3, (byte)0x9F, (byte)0xB3, (byte)0xD9,
+ (byte)0x51, (byte)0x51, (byte)0x38, (byte)0xBC,
+ (byte)0xD9, (byte)0xC1, (byte)0xD0, (byte)0x1E,
+ (byte)0x90, (byte)0x9B, (byte)0x43, (byte)0xEE,
+ (byte)0xD9, (byte)0xD6, (byte)0x3E, (byte)0x31,
+ (byte)0xEA, (byte)0x8E, (byte)0xB1, (byte)0xDC,
+ (byte)0xDE, (byte)0xFD, (byte)0xA4, (byte)0x77,
+ (byte)0x6C, (byte)0x4A, (byte)0x81, (byte)0x1F,
+ (byte)0xA4, (byte)0x82, (byte)0x02, (byte)0xE8,
+ (byte)0x30, (byte)0x82, (byte)0x02, (byte)0xE4,
+ (byte)0xA0, (byte)0x03, (byte)0x02, (byte)0x01,
+ (byte)0x11, (byte)0xA2, (byte)0x82, (byte)0x02,
+ (byte)0xDB, (byte)0x04, (byte)0x82, (byte)0x02,
+ (byte)0xD7, (byte)0x81, (byte)0x78, (byte)0x25,
+ (byte)0x75, (byte)0x92, (byte)0x7A, (byte)0xEC,
+ (byte)0xBE, (byte)0x31, (byte)0xF1, (byte)0x50,
+ (byte)0xE7, (byte)0xC1, (byte)0x32, (byte)0xA5,
+ (byte)0xCB, (byte)0x34, (byte)0x46, (byte)0x95,
+ (byte)0x2B, (byte)0x84, (byte)0xB7, (byte)0x06,
+ (byte)0x0E, (byte)0x15, (byte)0x02, (byte)0x74,
+ (byte)0xCA, (byte)0x18, (byte)0x5D, (byte)0xE8,
+ (byte)0x0E, (byte)0x1B, (byte)0xB7, (byte)0x77,
+ (byte)0x5A, (byte)0x6C, (byte)0xFB, (byte)0x94,
+ (byte)0x82, (byte)0x2B, (byte)0xE6, (byte)0x14,
+ (byte)0x0C, (byte)0xDA, (byte)0x22, (byte)0xA2,
+ (byte)0x42, (byte)0xD7, (byte)0xB0, (byte)0xFC,
+ (byte)0xCA, (byte)0x4A, (byte)0xEA, (byte)0xB8,
+ (byte)0x92, (byte)0xB5, (byte)0x8C, (byte)0x71,
+ (byte)0xED, (byte)0x2B, (byte)0x46, (byte)0xC5,
+ (byte)0xE5, (byte)0x47, (byte)0x76, (byte)0x29,
+ (byte)0x27, (byte)0x0F, (byte)0xFF, (byte)0x03,
+ (byte)0x72, (byte)0x13, (byte)0xAA, (byte)0xDB,
+ (byte)0x4E, (byte)0xFF, (byte)0x48, (byte)0x36,
+ (byte)0xAB, (byte)0x73, (byte)0xD7, (byte)0xDA,
+ (byte)0xF1, (byte)0x80, (byte)0x1B, (byte)0x5B,
+ (byte)0x9A, (byte)0x88, (byte)0x07, (byte)0x47,
+ (byte)0x43, (byte)0x27, (byte)0xD5, (byte)0x00,
+ (byte)0x04, (byte)0xEE, (byte)0xAF, (byte)0x53,
+ (byte)0x5C, (byte)0xCC, (byte)0x2C, (byte)0xC7,
+ (byte)0x2F, (byte)0x94, (byte)0x12, (byte)0x86,
+ (byte)0xEF, (byte)0xAC, (byte)0xB1, (byte)0x6C,
+ (byte)0xB0, (byte)0xB5, (byte)0x3D, (byte)0x92,
+ (byte)0xBD, (byte)0xBE, (byte)0x7B, (byte)0x1A,
+ (byte)0x39, (byte)0x4A, (byte)0x1E, (byte)0x91,
+ (byte)0xA4, (byte)0xDF, (byte)0x82, (byte)0x12,
+ (byte)0x2E, (byte)0x67, (byte)0x17, (byte)0x92,
+ (byte)0xB3, (byte)0x93, (byte)0x38, (byte)0x32,
+ (byte)0x94, (byte)0xF5, (byte)0xF7, (byte)0x09,
+ (byte)0x07, (byte)0x5E, (byte)0x21, (byte)0x12,
+ (byte)0x70, (byte)0x37, (byte)0xAF, (byte)0x5A,
+ (byte)0x2D, (byte)0xAC, (byte)0xFF, (byte)0x22,
+ (byte)0x46, (byte)0xA0, (byte)0x12, (byte)0x74,
+ (byte)0x1C, (byte)0xA1, (byte)0x68, (byte)0xC3,
+ (byte)0x64, (byte)0xDB, (byte)0xC3, (byte)0x9F,
+ (byte)0xAB, (byte)0x0E, (byte)0x19, (byte)0xFE,
+ (byte)0xD9, (byte)0xA4, (byte)0xAA, (byte)0x7B,
+ (byte)0x73, (byte)0xAD, (byte)0xC8, (byte)0xA8,
+ (byte)0xD5, (byte)0x29, (byte)0xAD, (byte)0x1F,
+ (byte)0xEF, (byte)0x54, (byte)0xAE, (byte)0x72,
+ (byte)0x02, (byte)0xD9, (byte)0x06, (byte)0x0D,
+ (byte)0x1A, (byte)0x94, (byte)0x7B, (byte)0xBC,
+ (byte)0x32, (byte)0x9A, (byte)0xBC, (byte)0x4B,
+ (byte)0x33, (byte)0xC2, (byte)0x02, (byte)0xA3,
+ (byte)0xF4, (byte)0xB1, (byte)0xED, (byte)0x76,
+ (byte)0x0D, (byte)0x59, (byte)0xCD, (byte)0x56,
+ (byte)0xCB, (byte)0xDC, (byte)0xCE, (byte)0xED,
+ (byte)0xFF, (byte)0x25, (byte)0x84, (byte)0x5E,
+ (byte)0x41, (byte)0xF9, (byte)0x42, (byte)0xBE,
+ (byte)0x73, (byte)0xAC, (byte)0xA2, (byte)0x20,
+ (byte)0x97, (byte)0xB7, (byte)0x88, (byte)0x77,
+ (byte)0x65, (byte)0x43, (byte)0x9F, (byte)0xEE,
+ (byte)0xF4, (byte)0x3A, (byte)0x7E, (byte)0x9B,
+ (byte)0x5B, (byte)0x54, (byte)0xD3, (byte)0x0D,
+ (byte)0x50, (byte)0x6D, (byte)0xF6, (byte)0x14,
+ (byte)0xB7, (byte)0x5A, (byte)0x34, (byte)0x0F,
+ (byte)0x1F, (byte)0xC7, (byte)0x39, (byte)0x99,
+ (byte)0x9B, (byte)0x96, (byte)0xE3, (byte)0xAD,
+ (byte)0x86, (byte)0xE3, (byte)0x6A, (byte)0x71,
+ (byte)0x63, (byte)0x04, (byte)0xAD, (byte)0x9C,
+ (byte)0x17, (byte)0x68, (byte)0x44, (byte)0xFE,
+ (byte)0x21, (byte)0x62, (byte)0xD5, (byte)0x99,
+ (byte)0x4A, (byte)0xDF, (byte)0x48, (byte)0xDE,
+ (byte)0x9A, (byte)0xD4, (byte)0xBB, (byte)0xA1,
+ (byte)0x9B, (byte)0xE7, (byte)0x2A, (byte)0x08,
+ (byte)0x80, (byte)0x3A, (byte)0x08, (byte)0xA4,
+ (byte)0xBA, (byte)0xBE, (byte)0x1E, (byte)0x81,
+ (byte)0x63, (byte)0x20, (byte)0xAC, (byte)0x9C,
+ (byte)0x42, (byte)0x2F, (byte)0xCA, (byte)0x06,
+ (byte)0x95, (byte)0x92, (byte)0x97, (byte)0x09,
+ (byte)0x3C, (byte)0x0C, (byte)0x5A, (byte)0x99,
+ (byte)0xFB, (byte)0xAB, (byte)0xEB, (byte)0xDE,
+ (byte)0xC4, (byte)0x09, (byte)0xD3, (byte)0xA3,
+ (byte)0xF0, (byte)0x65, (byte)0xDC, (byte)0x5F,
+ (byte)0xAA, (byte)0xBB, (byte)0x28, (byte)0xC0,
+ (byte)0x3E, (byte)0xBF, (byte)0x77, (byte)0xAE,
+ (byte)0xCC, (byte)0x3A, (byte)0xD3, (byte)0x31,
+ (byte)0x0D, (byte)0x9B, (byte)0x96, (byte)0xEF,
+ (byte)0x2C, (byte)0xED, (byte)0x60, (byte)0x63,
+ (byte)0xC5, (byte)0x8F, (byte)0xCA, (byte)0xB0,
+ (byte)0xA2, (byte)0x0B, (byte)0x49, (byte)0x5A,
+ (byte)0xB2, (byte)0x8F, (byte)0xEF, (byte)0xE4,
+ (byte)0x19, (byte)0xC0, (byte)0xC6, (byte)0x2D,
+ (byte)0xD3, (byte)0x4F, (byte)0xB2, (byte)0xED,
+ (byte)0xA3, (byte)0xA4, (byte)0x6F, (byte)0xAE,
+ (byte)0xD4, (byte)0xE9, (byte)0xA2, (byte)0x5A,
+ (byte)0xFB, (byte)0xB0, (byte)0x14, (byte)0xBD,
+ (byte)0x06, (byte)0x12, (byte)0xD7, (byte)0x91,
+ (byte)0x15, (byte)0x46, (byte)0x78, (byte)0xE4,
+ (byte)0xD1, (byte)0x73, (byte)0xCA, (byte)0xA5,
+ (byte)0xA5, (byte)0x64, (byte)0xC8, (byte)0x6F,
+ (byte)0xD1, (byte)0xBD, (byte)0xEA, (byte)0x74,
+ (byte)0xE4, (byte)0xCA, (byte)0x40, (byte)0x16,
+ (byte)0x9E, (byte)0x46, (byte)0x7C, (byte)0x25,
+ (byte)0x6C, (byte)0x32, (byte)0xB4, (byte)0x14,
+ (byte)0xF9, (byte)0x26, (byte)0x8A, (byte)0x3A,
+ (byte)0xDD, (byte)0x51, (byte)0x26, (byte)0x79,
+ (byte)0x43, (byte)0x27, (byte)0x2E, (byte)0xED,
+ (byte)0xC7, (byte)0x82, (byte)0x7C, (byte)0xCE,
+ (byte)0x43, (byte)0x03, (byte)0x60, (byte)0x2A,
+ (byte)0x9C, (byte)0xB2, (byte)0x71, (byte)0x41,
+ (byte)0xAB, (byte)0x3D, (byte)0xA6, (byte)0xB5,
+ (byte)0x51, (byte)0xBC, (byte)0x80, (byte)0x1F,
+ (byte)0x96, (byte)0x73, (byte)0x23, (byte)0x11,
+ (byte)0xED, (byte)0xC0, (byte)0x1D, (byte)0x0B,
+ (byte)0xA0, (byte)0x13, (byte)0xB3, (byte)0x2F,
+ (byte)0x16, (byte)0x59, (byte)0x64, (byte)0x45,
+ (byte)0xE8, (byte)0x68, (byte)0xFB, (byte)0xF9,
+ (byte)0x6F, (byte)0xB0, (byte)0x2B, (byte)0xFB,
+ (byte)0x39, (byte)0xBB, (byte)0x53, (byte)0x8F,
+ (byte)0xD2, (byte)0xAF, (byte)0x38, (byte)0x5E,
+ (byte)0xEF, (byte)0x5B, (byte)0xE2, (byte)0x98,
+ (byte)0xE8, (byte)0x46, (byte)0x3C, (byte)0x03,
+ (byte)0x71, (byte)0x46, (byte)0x8D, (byte)0x41,
+ (byte)0x92, (byte)0x32, (byte)0x85, (byte)0x8D,
+ (byte)0xBA, (byte)0x33, (byte)0x05, (byte)0xB1,
+ (byte)0xE4, (byte)0x56, (byte)0x3E, (byte)0xF5,
+ (byte)0x20, (byte)0x35, (byte)0xA6, (byte)0x74,
+ (byte)0xA2, (byte)0xBE, (byte)0x54, (byte)0x08,
+ (byte)0xB4, (byte)0xFC, (byte)0x1D, (byte)0x13,
+ (byte)0x84, (byte)0xBE, (byte)0x1C, (byte)0xC5,
+ (byte)0x3E, (byte)0x43, (byte)0x14, (byte)0x6F,
+ (byte)0xC0, (byte)0x3D, (byte)0xF4, (byte)0xDC,
+ (byte)0x66, (byte)0x4E, (byte)0xF0, (byte)0x3E,
+ (byte)0xD4, (byte)0xC6, (byte)0xE9, (byte)0x8D,
+ (byte)0x7D, (byte)0xB9, (byte)0xDC, (byte)0x9F,
+ (byte)0xBE, (byte)0x54, (byte)0x63, (byte)0x93,
+ (byte)0x49, (byte)0x2F, (byte)0x6A, (byte)0xC3,
+ (byte)0x34, (byte)0xC5, (byte)0xF7, (byte)0x76,
+ (byte)0xE8, (byte)0xD5, (byte)0x5B, (byte)0xD9,
+ (byte)0x41, (byte)0xCA, (byte)0x74, (byte)0x25,
+ (byte)0x25, (byte)0x09, (byte)0xF4, (byte)0xD3,
+ (byte)0x00, (byte)0x9F, (byte)0x7D, (byte)0xFB,
+ (byte)0x3D, (byte)0xAB, (byte)0x87, (byte)0xF7,
+ (byte)0xCE, (byte)0x42, (byte)0x0F, (byte)0x60,
+ (byte)0xEB, (byte)0x03, (byte)0x47, (byte)0x98,
+ (byte)0x0F, (byte)0xEB, (byte)0xA4, (byte)0x05,
+ (byte)0xE2, (byte)0x58, (byte)0x8F, (byte)0x44,
+ (byte)0x09, (byte)0xD3, (byte)0x66, (byte)0x1E,
+ (byte)0x69, (byte)0x89, (byte)0xB7, (byte)0xEE,
+ (byte)0x8B, (byte)0xA4, (byte)0x8E, (byte)0x05,
+ (byte)0x2D, (byte)0x2E, (byte)0xB3, (byte)0x5A,
+ (byte)0xAE, (byte)0xAB, (byte)0x80, (byte)0xD6,
+ (byte)0x5C, (byte)0x93, (byte)0x40, (byte)0x91,
+ (byte)0x53, (byte)0xE6, (byte)0x13, (byte)0xD5,
+ (byte)0x2F, (byte)0x64, (byte)0xF0, (byte)0x68,
+ (byte)0xD2, (byte)0x85, (byte)0x94, (byte)0xE5,
+ (byte)0x2D, (byte)0x73, (byte)0x10, (byte)0x59,
+ (byte)0x18, (byte)0xCD, (byte)0xED, (byte)0xBC,
+ (byte)0x05, (byte)0x97, (byte)0xFD, (byte)0xE7,
+ (byte)0x6F, (byte)0x5D, (byte)0x7C, (byte)0x46,
+ (byte)0x28, (byte)0x5F, (byte)0xC2, (byte)0xB4,
+ (byte)0x31, (byte)0xA5, (byte)0x2B, (byte)0x82,
+ (byte)0xAB, (byte)0x32, (byte)0x49, (byte)0xA5,
+ (byte)0xCD, (byte)0x91, (byte)0x37, (byte)0x97,
+ (byte)0xA1, (byte)0x85, (byte)0x8F, (byte)0xBB,
+ (byte)0x6E, (byte)0x1E, (byte)0x9F, (byte)0xFC,
+ (byte)0x10, (byte)0x3B, (byte)0x8A, (byte)0xF6,
+ (byte)0x9A, (byte)0x66, (byte)0xBD, (byte)0x75,
+ (byte)0x4F, (byte)0x1D, (byte)0xBA, (byte)0x64,
+ (byte)0x15, (byte)0xDD, (byte)0x9F, (byte)0x00,
+ (byte)0x6C, (byte)0x2F, (byte)0x87, (byte)0x20,
+ (byte)0x25, (byte)0xA2, (byte)0x09, (byte)0x9F,
+ (byte)0x5D, (byte)0x64, (byte)0xC9, (byte)0xA8,
+ (byte)0x32, (byte)0x59, (byte)0x90, (byte)0x1D,
+ (byte)0x78, (byte)0xFE, (byte)0x5A, (byte)0xA2,
+ (byte)0x1F, (byte)0x9B, (byte)0x22, (byte)0xBE,
+ (byte)0x8F, (byte)0xEA, (byte)0x59, (byte)0x5B,
+ (byte)0x96, (byte)0xE3, (byte)0x4A, (byte)0xB2,
+ (byte)0x71, (byte)0x65, (byte)0xB7, (byte)0x3C,
+ (byte)0xC6, (byte)0x1B, (byte)0xD6, (byte)0x80,
+ (byte)0x90, (byte)0xD2, (byte)0xF2, (byte)0x6F,
+ (byte)0xA2, (byte)0x68, (byte)0x53, (byte)0xC0,
+ (byte)0x44, (byte)0xAF, (byte)0xD4, (byte)0x68,
+ (byte)0x12, (byte)0xFF, (byte)0xB4, (byte)0x36,
+ (byte)0x34, (byte)0x43, (byte)0xAC, (byte)0x1C,
+ };
+}
--- a/jdk/test/sun/security/krb5/auto/KDC.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/sun/security/krb5/auto/KDC.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -691,7 +691,10 @@
new KerberosTime(new Date()),
body.from,
till, body.rtime,
- body.addresses,
+ body.addresses != null // always set caddr
+ ? body.addresses
+ : new HostAddresses(
+ new InetAddress[]{InetAddress.getLocalHost()}),
null);
EncryptionKey skey = keyForUser(body.sname, e3, true);
if (skey == null) {
@@ -716,7 +719,10 @@
till, body.rtime,
body.crealm,
body.sname,
- body.addresses
+ body.addresses != null // always set caddr
+ ? body.addresses
+ : new HostAddresses(
+ new InetAddress[]{InetAddress.getLocalHost()})
);
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
TGSRep tgsRep = new TGSRep(null,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/NoAddresses.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7032354
+ * @run main/othervm NoAddresses 1
+ * @run main/othervm NoAddresses 2
+ * @run main/othervm/fail NoAddresses 3
+ * @summary no-addresses should not be used on acceptor side
+ */
+
+import java.net.InetAddress;
+import org.ietf.jgss.ChannelBinding;
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.Config;
+
+public class NoAddresses {
+
+ public static void main(String[] args)
+ throws Exception {
+
+ OneKDC kdc = new OneKDC(null);
+ kdc.writeJAASConf();
+ KDC.saveConfig(OneKDC.KRB5_CONF, kdc,
+ "noaddresses = false",
+ "default_keytab_name = " + OneKDC.KTAB);
+ Config.refresh();
+
+ Context c = Context.fromJAAS("client");
+ Context s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+
+ InetAddress initiator = InetAddress.getLocalHost();
+ InetAddress acceptor = InetAddress.getLocalHost();
+ switch (args[0]) {
+ case "1":
+ // no initiator host address available, should be OK
+ break;
+ case "2":
+ // correct initiator host address, still fine
+ c.x().setChannelBinding(
+ new ChannelBinding(initiator, acceptor, null));
+ s.x().setChannelBinding(
+ new ChannelBinding(initiator, acceptor, null));
+ break;
+ case "3":
+ // incorrect initiator host address, fail
+ initiator = InetAddress.getByAddress(new byte[]{1,1,1,1});
+ c.x().setChannelBinding(
+ new ChannelBinding(initiator, acceptor, null));
+ s.x().setChannelBinding(
+ new ChannelBinding(initiator, acceptor, null));
+ break;
+ }
+
+ Context.handshake(c, s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6976117
+ * @summary SSLContext.getInstance("TLSv1.1") returns SSLEngines/SSLSockets
+ * without TLSv1.1 enabled
+ */
+
+import javax.net.ssl.*;
+
+public class SSLContextVersion {
+ static enum ContextVersion {
+ TLS_CV_01("SSL", "TLSv1", "TLSv1.2"),
+ TLS_CV_02("TLS", "TLSv1", "TLSv1.2"),
+ TLS_CV_03("SSLv3", "TLSv1", "TLSv1.2"),
+ TLS_CV_04("TLSv1", "TLSv1", "TLSv1.2"),
+ TLS_CV_05("TLSv1.1", "TLSv1.1", "TLSv1.2"),
+ TLS_CV_06("TLSv1.2", "TLSv1.2", "TLSv1.2"),
+ TLS_CV_07("Default", "TLSv1", "TLSv1.2");
+
+ final String contextVersion;
+ final String defaultProtocolVersion;
+ final String supportedProtocolVersion;
+
+ ContextVersion(String contextVersion, String defaultProtocolVersion,
+ String supportedProtocolVersion) {
+ this.contextVersion = contextVersion;
+ this.defaultProtocolVersion = defaultProtocolVersion;
+ this.supportedProtocolVersion = supportedProtocolVersion;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (ContextVersion cv : ContextVersion.values()) {
+ System.out.println("Checking SSLContext of " + cv.contextVersion);
+ SSLContext context = SSLContext.getInstance(cv.contextVersion);
+
+ // Default SSLContext is initialized automatically.
+ if (!cv.contextVersion.equals("Default")) {
+ // Use default TK, KM and random.
+ context.init((KeyManager[])null, (TrustManager[])null, null);
+ }
+
+ SSLParameters parameters = context.getDefaultSSLParameters();
+
+ String[] protocols = parameters.getProtocols();
+ String[] ciphers = parameters.getCipherSuites();
+
+ if (protocols.length == 0 || ciphers.length == 0) {
+ throw new Exception("No default protocols or cipher suites");
+ }
+
+ boolean isMatch = false;
+ for (String protocol : protocols) {
+ System.out.println("\tdefault protocol version " + protocol);
+ if (protocol.equals(cv.defaultProtocolVersion)) {
+ isMatch = true;
+ break;
+ }
+ }
+
+ if (!isMatch) {
+ throw new Exception("No matched default protocol");
+ }
+
+ parameters = context.getSupportedSSLParameters();
+
+ protocols = parameters.getProtocols();
+ ciphers = parameters.getCipherSuites();
+
+ if (protocols.length == 0 || ciphers.length == 0) {
+ throw new Exception("No default protocols or cipher suites");
+ }
+
+ isMatch = false;
+ for (String protocol : protocols) {
+ System.out.println("\tsupported protocol version " + protocol);
+ if (protocol.equals(cv.supportedProtocolVersion)) {
+ isMatch = true;
+ break;
+ }
+ }
+
+ if (!isMatch) {
+ throw new Exception("No matched default protocol");
+ }
+ System.out.println("\t... Success");
+ }
+ }
+}
--- a/jdk/test/tools/launcher/ExecutionEnvironment.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/tools/launcher/ExecutionEnvironment.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
*/
/*
- * This test tests for various things as follows:
+ * This tests for various things as follows:
* Ensures that:
* 1. uneccessary execs do not occur
* 2. the environment is pristine, users environment variable wrt.
@@ -84,7 +84,9 @@
static int errors = 0;
static int passes = 0;
- private static void createTestJar() {
+ static final String LIBJVM = TestHelper.isWindows ? "jvm.dll" : "libjvm.so";
+
+ static void createTestJar() {
try {
List<String> codeList = new ArrayList<String>();
codeList.add("static void printValue(String name, boolean property) {\n");
@@ -127,6 +129,7 @@
testJarFile.getAbsolutePath());
if (!tr.isNotZeroOutput()) {
+ System.out.println(tr);
throw new RuntimeException("Error: No output at all. Did the test execute ?");
}
@@ -177,7 +180,6 @@
Map<String, String> env = new HashMap<String, String>();
-
if (TestHelper.isLinux) {
for (String x : LD_PATH_STRINGS) {
String pairs[] = x.split("=");
@@ -209,7 +211,7 @@
verifyJavaLibraryPathOverride(tr, true);
// try changing the model from 32 to 64 bit
- if (TestHelper.java64Cmd != null && TestHelper.is32Bit) {
+ if (TestHelper.dualModePresent() && TestHelper.is32Bit) {
// verify the override occurs
env.clear();
for (String x : LD_PATH_STRINGS) {
@@ -326,7 +328,7 @@
File symLink = null;
String libPathPrefix = TestHelper.isSDK ? "jre/lib" : "/lib";
symLink = new File(TestHelper.JAVAHOME, libPathPrefix +
- TestHelper.getJreArch() + "/libjvm.so");
+ TestHelper.getJreArch() + "/" + LIBJVM);
if (symLink.exists()) {
System.out.println("FAIL: The symlink exists " +
symLink.getAbsolutePath());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/Test7029048.java Tue Apr 12 14:23:03 2011 -0700
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7029048
+ * @summary Checks for LD_LIBRARY_PATH on *nixes
+ * @compile -XDignore.symbol.file ExecutionEnvironment.java TestHelper.java Test7029048.java
+ * @run main Test7029048
+ */
+
+/*
+ * 7029048: test for LD_LIBRARY_PATH set to different paths pointing which may
+ * contain a libjvm.so and may not, but we test to ensure that the launcher
+ * behaves correctly in all cases.
+ */
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Test7029048 {
+
+ static int passes = 0;
+ static int errors = 0;
+
+ private static final String LIBJVM = ExecutionEnvironment.LIBJVM;
+ private static final String LD_LIBRARY_PATH =
+ ExecutionEnvironment.LD_LIBRARY_PATH;
+ private static final String LD_LIBRARY_PATH_32 =
+ ExecutionEnvironment.LD_LIBRARY_PATH_32;
+ private static final String LD_LIBRARY_PATH_64 =
+ ExecutionEnvironment.LD_LIBRARY_PATH_64;
+
+ private static final File libDir =
+ new File(System.getProperty("sun.boot.library.path"));
+ private static final File srcServerDir = new File(libDir, "server");
+ private static final File srcLibjvmSo = new File(srcServerDir, LIBJVM);
+
+ private static final File dstLibDir = new File("lib");
+ private static final File dstLibArchDir =
+ new File(dstLibDir, TestHelper.getJreArch());
+
+ private static final File dstServerDir = new File(dstLibArchDir, "server");
+ private static final File dstServerLibjvm = new File(dstServerDir, LIBJVM);
+
+ private static final File dstClientDir = new File(dstLibArchDir, "client");
+ private static final File dstClientLibjvm = new File(dstClientDir, LIBJVM);
+
+ // used primarily to test the solaris variants in dual mode
+ private static final File dstOtherArchDir;
+ private static final File dstOtherServerDir;
+ private static final File dstOtherServerLibjvm;
+
+ private static final Map<String, String> env = new HashMap<>();
+
+ static {
+ if (TestHelper.isDualMode) {
+ dstOtherArchDir = new File(dstLibDir, TestHelper.getComplementaryJreArch());
+ dstOtherServerDir = new File(dstOtherArchDir, "server");
+ dstOtherServerLibjvm = new File(dstOtherServerDir, LIBJVM);
+ } else {
+ dstOtherArchDir = null;
+ dstOtherServerDir = null;
+ dstOtherServerLibjvm = null;
+ }
+ }
+
+ static String getValue(String name, List<String> in) {
+ for (String x : in) {
+ String[] s = x.split("=");
+ if (name.equals(s[0].trim())) {
+ return s[1].trim();
+ }
+ }
+ return null;
+ }
+
+ static void run(boolean want32, String dflag, Map<String, String> env,
+ int nLLPComponents, String caseID) {
+ final boolean want64 = want32 == false;
+ env.put(ExecutionEnvironment.JLDEBUG_KEY, "true");
+ List<String> cmdsList = new ArrayList<>();
+
+ // only for a dual-mode system
+ if (want64 && TestHelper.isDualMode) {
+ cmdsList.add(TestHelper.java64Cmd);
+ } else {
+ cmdsList.add(TestHelper.javaCmd); // a 32-bit java command for all
+ }
+
+ /*
+ * empty or null strings can confuse the ProcessBuilder. A null flag
+ * indicates that the appropriate data model is enforced on the chosen
+ * launcher variant.
+ */
+
+ if (dflag != null) {
+ cmdsList.add(dflag);
+ } else {
+ cmdsList.add(want32 ? "-d32" : "-d64");
+ }
+ cmdsList.add("-server");
+ cmdsList.add("-jar");
+ cmdsList.add(ExecutionEnvironment.testJarFile.getAbsolutePath());
+ String[] cmds = new String[cmdsList.size()];
+ TestHelper.TestResult tr = TestHelper.doExec(env, cmdsList.toArray(cmds));
+ analyze(tr, nLLPComponents, caseID);
+ }
+
+ // no cross launch, ie. no change to the data model.
+ static void run(Map<String, String> env, int nLLPComponents, String caseID)
+ throws IOException {
+ boolean want32 = TestHelper.is32Bit;
+ run(want32, null, env, nLLPComponents, caseID);
+ }
+
+ static void analyze(TestHelper.TestResult tr, int nLLPComponents, String caseID) {
+ String envValue = getValue(LD_LIBRARY_PATH, tr.testOutput);
+ /*
+ * the envValue can never be null, since the test code should always
+ * print a "null" string.
+ */
+ if (envValue == null) {
+ System.out.println(tr);
+ throw new RuntimeException("NPE, likely a program crash ??");
+ }
+ String values[] = envValue.split(File.pathSeparator);
+ if (values.length == nLLPComponents) {
+ System.out.println(caseID + " :OK");
+ passes++;
+ } else {
+ System.out.println("FAIL: test7029048, " + caseID);
+ System.out.println(" expected " + nLLPComponents
+ + " but got " + values.length);
+ System.out.println(envValue);
+ System.out.println(tr);
+ errors++;
+ }
+ }
+
+ /*
+ * A crucial piece, specifies what we should expect, given the conditions.
+ * That is for a given enum type, the value indicates how many absolute
+ * environment variables that can be expected. This value is used to base
+ * the actual expected values by adding the set environment variable usually
+ * it is 1, but it could be more if the test wishes to set more paths in
+ * the future.
+ */
+ private static enum LLP_VAR {
+ LLP_SET_NON_EXISTENT_PATH(0), // env set, but the path does not exist
+ LLP_SET_EMPTY_PATH(0), // env set, with a path but no libjvm.so
+ LLP_SET_WITH_JVM(3); // env set, with a libjvm.so
+ private final int value;
+ LLP_VAR(int i) {
+ this.value = i;
+ }
+ }
+
+ /*
+ * test for 7029048
+ */
+ static void test7029048() throws IOException {
+ String desc = null;
+ for (LLP_VAR v : LLP_VAR.values()) {
+ switch (v) {
+ case LLP_SET_WITH_JVM:
+ // copy the files into the directory structures
+ TestHelper.copyFile(srcLibjvmSo, dstServerLibjvm);
+ // does not matter if it is client or a server
+ TestHelper.copyFile(srcLibjvmSo, dstClientLibjvm);
+ // does not matter if the arch do not match either
+ if (TestHelper.isDualMode) {
+ TestHelper.copyFile(srcLibjvmSo, dstOtherServerLibjvm);
+ }
+ desc = "LD_LIBRARY_PATH should be set";
+ break;
+ case LLP_SET_EMPTY_PATH:
+ if (!dstClientDir.exists()) {
+ Files.createDirectories(dstClientDir.toPath());
+ } else {
+ Files.deleteIfExists(dstClientLibjvm.toPath());
+ }
+
+ if (!dstServerDir.exists()) {
+ Files.createDirectories(dstServerDir.toPath());
+ } else {
+ Files.deleteIfExists(dstServerLibjvm.toPath());
+ }
+
+ if (TestHelper.isDualMode) {
+ if (!dstOtherServerDir.exists()) {
+ Files.createDirectories(dstOtherServerDir.toPath());
+ } else {
+ Files.deleteIfExists(dstOtherServerLibjvm.toPath());
+ }
+ }
+
+ desc = "LD_LIBRARY_PATH should not be set";
+ break;
+ case LLP_SET_NON_EXISTENT_PATH:
+ if (dstLibDir.exists()) {
+ TestHelper.recursiveDelete(dstLibDir);
+ }
+ desc = "LD_LIBRARY_PATH should not be set";
+ break;
+ default:
+ throw new RuntimeException("unknown case");
+ }
+
+ /*
+ * Case 1: set the server path
+ */
+ env.clear();
+ env.put(LD_LIBRARY_PATH, dstServerDir.getAbsolutePath());
+ run(env, v.value + 1, "Case 1: " + desc);
+
+ /*
+ * Case 2: repeat with client path
+ */
+ env.clear();
+ env.put(LD_LIBRARY_PATH, dstClientDir.getAbsolutePath());
+ run(env, v.value + 1, "Case 2: " + desc);
+
+ if (!TestHelper.isDualMode) {
+ continue; // nothing more to do for Linux
+ }
+
+ // Tests applicable only to solaris.
+
+ // initialize test variables for dual mode operations
+ final File dst32ServerDir = TestHelper.is32Bit
+ ? dstServerDir
+ : dstOtherServerDir;
+
+ final File dst64ServerDir = TestHelper.is64Bit
+ ? dstServerDir
+ : dstOtherServerDir;
+
+ /*
+ * Case 3: set the appropriate LLP_XX flag,
+ * java32 -d32, LLP_32 is relevant, LLP_64 is ignored
+ * java64 -d64, LLP_64 is relevant, LLP_32 is ignored
+ */
+ env.clear();
+ env.put(LD_LIBRARY_PATH_32, dst32ServerDir.getAbsolutePath());
+ env.put(LD_LIBRARY_PATH_64, dst64ServerDir.getAbsolutePath());
+ run(TestHelper.is32Bit, null, env, v.value + 1, "Case 3: " + desc);
+
+ /*
+ * Case 4: we are in dual mode environment, running 64-bit then
+ * we have the following scenarios:
+ * java32 -d64, LLP_64 is relevant, LLP_32 is ignored
+ * java64 -d32, LLP_32 is relevant, LLP_64 is ignored
+ */
+ if (TestHelper.dualModePresent()) {
+ run(true, "-d64", env, v.value + 1, "Case 4A: " + desc);
+ run(false,"-d32", env, v.value + 1, "Case 4B: " + desc);
+ }
+ }
+ return;
+ }
+
+ public static void main(String... args) throws Exception {
+ if (TestHelper.isWindows) {
+ System.out.println("Warning: noop on windows");
+ return;
+ }
+ // create our test jar first
+ ExecutionEnvironment.createTestJar();
+
+ // run the tests
+ test7029048();
+ if (errors > 0) {
+ throw new Exception("Test7029048: FAIL: with "
+ + errors + " errors and passes " + passes);
+ } else if (TestHelper.dualModePresent() && passes < 15) {
+ throw new Exception("Test7029048: FAIL: " +
+ "all tests did not run, expected " + 15 + " got " + passes);
+ } else if (TestHelper.isSolaris && passes < 9) {
+ throw new Exception("Test7029048: FAIL: " +
+ "all tests did not run, expected " + 9 + " got " + passes);
+ } else if (TestHelper.isLinux && passes < 6) {
+ throw new Exception("Test7029048: FAIL: " +
+ "all tests did not run, expected " + 6 + " got " + passes);
+ } else {
+ System.out.println("Test7029048: PASS " + passes);
+ }
+ }
+}
--- a/jdk/test/tools/launcher/TestHelper.java Fri Apr 08 10:31:14 2011 -0700
+++ b/jdk/test/tools/launcher/TestHelper.java Tue Apr 12 14:23:03 2011 -0700
@@ -1,6 +1,5 @@
-
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,20 +21,28 @@
* questions.
*/
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.FileVisitResult;
+import java.nio.file.SimpleFileVisitor;
import javax.tools.ToolProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.tools.JavaCompiler;
+import static java.nio.file.StandardCopyOption.*;
+
/**
- * This class provides some common utilites for the launcher tests.
+ * This class provides some common utilities for the launcher tests.
*/
public enum TestHelper {
INSTANCE;
@@ -101,6 +108,13 @@
}
/*
+ * is a dual mode available in the test jdk
+ */
+ static boolean dualModePresent() {
+ return isDualMode && java64Cmd != null;
+ }
+
+ /*
* usually the jre/lib/arch-name is the same as os.arch, except for x86.
*/
static String getJreArch() {
@@ -109,6 +123,27 @@
}
/*
+ * get the complementary jre arch ie. if sparc then return sparcv9 and
+ * vice-versa.
+ */
+ static String getComplementaryJreArch() {
+ String arch = System.getProperty("os.arch");
+ if (arch != null) {
+ switch (arch) {
+ case "sparc":
+ return "sparcv9";
+ case "sparcv9":
+ return "sparc";
+ case "x86":
+ return "amd64";
+ case "amd64":
+ return "i386";
+ }
+ }
+ return null;
+ }
+
+ /*
* A convenience method to create a jar with jar file name and defs
*/
static void createJar(File jarName, String... mainDefs)
@@ -168,6 +203,44 @@
}
}
+ static void copyFile(File src, File dst) throws IOException {
+ Path parent = dst.toPath().getParent();
+ if (parent != null) {
+ Files.createDirectories(parent);
+ }
+ Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
+ }
+
+ static void recursiveDelete(File target) throws IOException {
+ if (!target.exists()) {
+ return;
+ }
+ Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+ try {
+ Files.deleteIfExists(dir);
+ } catch (IOException ex) {
+ System.out.println("Error: could not delete: " + dir.toString());
+ System.out.println(ex.getMessage());
+ return FileVisitResult.TERMINATE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ try {
+ Files.deleteIfExists(file);
+ } catch (IOException ex) {
+ System.out.println("Error: could not delete: " + file.toString());
+ System.out.println(ex.getMessage());
+ return FileVisitResult.TERMINATE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
static TestResult doExec(String...cmds) {
return doExec(null, cmds);
}
@@ -187,7 +260,7 @@
}
BufferedReader rdr = null;
try {
- List<String> outputList = new ArrayList<String>();
+ List<String> outputList = new ArrayList<>();
pb.redirectErrorStream(true);
Process p = pb.start();
rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
@@ -198,7 +271,9 @@
}
p.waitFor();
p.destroy();
- return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList);
+
+ return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
+ env, new Throwable("current stack of the test"));
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex.getMessage());
@@ -213,11 +288,16 @@
StringBuilder status;
int exitValue;
List<String> testOutput;
+ Map<String, String> env;
+ Throwable t;
- public TestResult(String str, int rv, List<String> oList) {
+ public TestResult(String str, int rv, List<String> oList,
+ Map<String, String> env, Throwable t) {
status = new StringBuilder("Executed command: " + str + "\n");
exitValue = rv;
testOutput = oList;
+ this.env = env;
+ this.t = t;
}
void appendStatus(String x) {
@@ -262,11 +342,21 @@
@Override
public String toString() {
- status = status.append("++++Test Output Begin++++\n");
+ status.append("++++Begin Test Info++++\n");
+ status.append("++++Test Environment++++\n");
+ for (String x : env.keySet()) {
+ status.append(x).append("=").append(env.get(x)).append("\n");
+ }
+ status.append("++++Test Output++++\n");
for (String x : testOutput) {
appendStatus(x);
}
- status = status.append("++++Test Output End++++\n");
+ status.append("++++Test Stack Trace++++\n");
+ status.append(t.toString());
+ for (StackTraceElement e : t.getStackTrace()) {
+ status.append(e.toString());
+ }
+ status.append("++++End of Test Info++++\n");
return status.toString();
}