# HG changeset patch # User asaha # Date 1302643383 25200 # Node ID e142148d8b5444e07602809dfbedbced25be37a5 # Parent 557bd9b5d92f1517540dd329875b5c2dfa10be7b# Parent 9128eace50f5e0624d81d7621cdfb9abd5260d78 Merge diff -r 557bd9b5d92f -r e142148d8b54 make/com/sun/java/pack/Makefile --- a/make/com/sun/java/pack/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/com/sun/java/pack/mapfile-vers-unpack200 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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: + *; +}; diff -r 557bd9b5d92f -r e142148d8b54 make/common/Mapfile-vers.gmk --- a/make/common/Mapfile-vers.gmk Fri Apr 08 10:31:14 2011 -0700 +++ b/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) diff -r 557bd9b5d92f -r e142148d8b54 make/common/Program.gmk --- a/make/common/Program.gmk Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/java/Makefile --- a/make/java/java/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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) diff -r 557bd9b5d92f -r e142148d8b54 make/java/main/java/Makefile --- a/make/java/main/java/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/main/java/mapfile-amd64 --- a/make/java/main/java/mapfile-amd64 Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/main/java/mapfile-i586 --- a/make/java/main/java/mapfile-i586 Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/main/java/mapfile-sparc --- a/make/java/main/java/mapfile-sparc Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/main/java/mapfile-sparcv9 --- a/make/java/main/java/mapfile-sparcv9 Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/java/management/Makefile --- a/make/java/management/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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 # diff -r 557bd9b5d92f -r e142148d8b54 make/mksample/Makefile --- a/make/mksample/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/mksample/forkjoin/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/mksample/forkjoin/mergesort/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 make/mksample/nio/Makefile --- a/make/mksample/nio/Makefile Fri Apr 08 10:31:14 2011 -0700 +++ b/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:: diff -r 557bd9b5d92f -r e142148d8b54 make/mksample/nio/chatserver/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/bin/jli_util.h --- a/src/share/bin/jli_util.h Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/lang/Character.java --- a/src/share/classes/java/lang/Character.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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); diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/lang/reflect/AccessibleObject.java --- a/src/share/classes/java/lang/reflect/AccessibleObject.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 + } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/lang/reflect/Constructor.java --- a/src/share/classes/java/lang/reflect/Constructor.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/lang/reflect/Field.java --- a/src/share/classes/java/lang/reflect/Field.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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}. * - *

If this {@code Field} object enforces Java language access control, and + *

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}. * - *

If this {@code Field} object enforces Java language access control, and + *

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 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); } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/lang/reflect/Method.java --- a/src/share/classes/java/lang/reflect/Method.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/nio/file/Files.java --- a/src/share/classes/java/nio/file/Files.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/nio/file/Path.java --- a/src/share/classes/java/nio/file/Path.java Fri Apr 08 10:31:14 2011 -0700 +++ b/src/share/classes/java/nio/file/Path.java Tue Apr 12 14:23:03 2011 -0700 @@ -550,18 +550,21 @@ *

If this path is relative then its absolute path is first obtained, * as if by invoking the {@link #toAbsolutePath toAbsolutePath} method. * - *

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 real - * path, 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. + *

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 real path, 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 real 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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/sql/DriverManager.java --- a/src/share/classes/java/sql/DriverManager.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 registeredDrivers = new CopyOnWriteArrayList(); + private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList(); 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() { + 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() { + public Void run() { ServiceLoader 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 + "]"); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/AbstractQueue.java --- a/src/share/classes/java/util/AbstractQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/ArrayDeque.java --- a/src/share/classes/java/util/ArrayDeque.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/Deque.java --- a/src/share/classes/java/util/Deque.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/EnumMap.java --- a/src/share/classes/java/util/EnumMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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> 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> - implements Map.Entry - { + private class EntryIterator extends EnumMapIterator> { + private Entry lastReturnedEntry = null; + public Map.Entry 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 { + 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 true 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 m = (Map)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 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--; + } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/IdentityHashMap.java --- a/src/share/classes/java/util/IdentityHashMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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> - implements Map.Entry { + private Entry lastReturnedEntry = null; + public Map.Entry 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 { + 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"); + } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/NavigableMap.java --- a/src/share/classes/java/util/NavigableMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/NavigableSet.java --- a/src/share/classes/java/util/NavigableSet.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/Queue.java --- a/src/share/classes/java/util/Queue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/AbstractExecutorService.java --- a/src/share/classes/java/util/concurrent/AbstractExecutorService.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ArrayBlockingQueue.java --- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/BlockingDeque.java --- a/src/share/classes/java/util/concurrent/BlockingDeque.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/BlockingQueue.java --- a/src/share/classes/java/util/concurrent/BlockingQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/BrokenBarrierException.java --- a/src/share/classes/java/util/concurrent/BrokenBarrierException.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Callable.java --- a/src/share/classes/java/util/concurrent/Callable.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/CancellationException.java --- a/src/share/classes/java/util/concurrent/CancellationException.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/CompletionService.java --- a/src/share/classes/java/util/concurrent/CompletionService.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentHashMap.java --- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java --- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentMap.java --- a/src/share/classes/java/util/concurrent/ConcurrentMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java --- a/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java --- a/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java --- a/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java --- a/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/CountDownLatch.java --- a/src/share/classes/java/util/concurrent/CountDownLatch.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/CyclicBarrier.java --- a/src/share/classes/java/util/concurrent/CyclicBarrier.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/DelayQueue.java --- a/src/share/classes/java/util/concurrent/DelayQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Delayed.java --- a/src/share/classes/java/util/concurrent/Delayed.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Exchanger.java --- a/src/share/classes/java/util/concurrent/Exchanger.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ExecutionException.java --- a/src/share/classes/java/util/concurrent/ExecutionException.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Executor.java --- a/src/share/classes/java/util/concurrent/Executor.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ExecutorCompletionService.java --- a/src/share/classes/java/util/concurrent/ExecutorCompletionService.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ExecutorService.java --- a/src/share/classes/java/util/concurrent/ExecutorService.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Executors.java --- a/src/share/classes/java/util/concurrent/Executors.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ForkJoinPool.java --- a/src/share/classes/java/util/concurrent/ForkJoinPool.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ForkJoinTask.java --- a/src/share/classes/java/util/concurrent/ForkJoinTask.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java --- a/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Future.java --- a/src/share/classes/java/util/concurrent/Future.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/FutureTask.java --- a/src/share/classes/java/util/concurrent/FutureTask.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/LinkedBlockingDeque.java --- a/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/LinkedBlockingQueue.java --- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/LinkedTransferQueue.java --- a/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Phaser.java --- a/src/share/classes/java/util/concurrent/Phaser.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/PriorityBlockingQueue.java --- a/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RecursiveAction.java --- a/src/share/classes/java/util/concurrent/RecursiveAction.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RecursiveTask.java --- a/src/share/classes/java/util/concurrent/RecursiveTask.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RejectedExecutionException.java --- a/src/share/classes/java/util/concurrent/RejectedExecutionException.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RejectedExecutionHandler.java --- a/src/share/classes/java/util/concurrent/RejectedExecutionHandler.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RunnableFuture.java --- a/src/share/classes/java/util/concurrent/RunnableFuture.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/RunnableScheduledFuture.java --- a/src/share/classes/java/util/concurrent/RunnableScheduledFuture.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ScheduledExecutorService.java --- a/src/share/classes/java/util/concurrent/ScheduledExecutorService.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ScheduledFuture.java --- a/src/share/classes/java/util/concurrent/ScheduledFuture.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java --- a/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/Semaphore.java --- a/src/share/classes/java/util/concurrent/Semaphore.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/SynchronousQueue.java --- a/src/share/classes/java/util/concurrent/SynchronousQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ThreadFactory.java --- a/src/share/classes/java/util/concurrent/ThreadFactory.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ThreadLocalRandom.java --- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/ThreadPoolExecutor.java --- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/TimeUnit.java --- a/src/share/classes/java/util/concurrent/TimeUnit.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/TimeoutException.java --- a/src/share/classes/java/util/concurrent/TimeoutException.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/TransferQueue.java --- a/src/share/classes/java/util/concurrent/TransferQueue.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicInteger.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicLong.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicLong.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicReference.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicReference.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java --- a/src/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/atomic/package-info.java --- a/src/share/classes/java/util/concurrent/atomic/package-info.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java --- a/src/share/classes/java/util/concurrent/locks/AbstractOwnableSynchronizer.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java --- a/src/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java --- a/src/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/Condition.java --- a/src/share/classes/java/util/concurrent/locks/Condition.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/Lock.java --- a/src/share/classes/java/util/concurrent/locks/Lock.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/LockSupport.java --- a/src/share/classes/java/util/concurrent/locks/LockSupport.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/ReadWriteLock.java --- a/src/share/classes/java/util/concurrent/locks/ReadWriteLock.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/ReentrantLock.java --- a/src/share/classes/java/util/concurrent/locks/ReentrantLock.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java --- a/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/locks/package-info.java --- a/src/share/classes/java/util/concurrent/locks/package-info.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/concurrent/package-info.java --- a/src/share/classes/java/util/concurrent/package-info.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/jar/JarFile.java --- a/src/share/classes/java/util/jar/JarFile.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 JarFile 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"))); } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/jar/JarInputStream.java --- a/src/share/classes/java/util/jar/JarInputStream.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/jar/JarVerifier.java --- a/src/share/classes/java/util/jar/JarVerifier.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/java/util/zip/DeflaterOutputStream.java --- a/src/share/classes/java/util/zip/DeflaterOutputStream.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/javax/swing/plaf/LayerUI.java --- a/src/share/classes/javax/swing/plaf/LayerUI.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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) */ diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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"); } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/nio/ch/IOUtil.java --- a/src/share/classes/sun/nio/ch/IOUtil.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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) diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/nio/fs/Util.java --- a/src/share/classes/sun/nio/fs/Util.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; + } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java --- a/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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) { diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/jgss/krb5/InitialToken.java --- a/src/share/classes/sun/security/jgss/krb5/InitialToken.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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]; } } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/krb5/KrbApReq.java --- a/src/share/classes/sun/security/krb5/KrbApReq.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 Credentials 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); } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/pkcs/PKCS7.java --- a/src/share/classes/sun/security/pkcs/PKCS7.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 implCRLs = new HashSet(crls.length); + Set 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 intResult = new Vector(); + List 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; } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/pkcs/SignerInfo.java --- a/src/share/classes/sun/security/pkcs/SignerInfo.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 certList = new ArrayList(); + ArrayList 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. */ diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/CipherSuiteList.java --- a/src/share/classes/sun/security/ssl/CipherSuiteList.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 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 cipherSuites = new TreeSet<>(); - Collection 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; - } - } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java --- a/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 props = new HashMap<>(); - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - 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() { - 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; - } -} diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/JsseJce.java --- a/src/share/classes/sun/security/ssl/JsseJce.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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) { diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/ProtocolList.java --- a/src/share/classes/sun/security/ssl/ProtocolList.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 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 - }); - } - } - } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLContextImpl.java --- a/src/share/classes/sun/security/ssl/SSLContextImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 allowedCipherSuites = + CipherSuite.allowedCipherSuites(); + + ArrayList 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 props = new HashMap<>(); + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + 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() { + 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; + } + } + } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLEngineImpl.java --- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); } /** diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java --- a/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLServerSocketImpl.java --- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java --- a/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); } } diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SSLSocketImpl.java --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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(); } /** diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/ssl/SunJSSE.java --- a/src/share/classes/sun/security/ssl/SunJSSE.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/util/ManifestEntryVerifier.java --- a/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 verifiedSigners, - Hashtable sigFileSigners) + public CodeSigner[] verify(Map verifiedSigners, + Map sigFileSigners) throws JarException { if (skip) { diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/security/util/SignatureFileManifest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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. + *

+ * 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. + *

+ * 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. + *

+ * 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 createdDigests; @@ -83,6 +86,7 @@ * @param rawBytes the raw bytes of the signature block file */ public SignatureFileVerifier(ArrayList 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 signers, + public void process(Map signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException @@ -197,31 +194,86 @@ } - private void processImpl(Hashtable signers, + private void processImpl(Map 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 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> 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> 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 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 signers, String name) { + Map signers, String name) { CodeSigner[] oldSigners = signers.get(name); diff -r 557bd9b5d92f -r e142148d8b54 src/share/classes/sun/util/calendar/ZoneInfoFile.java --- a/src/share/classes/sun/util/calendar/ZoneInfoFile.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java --- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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); } diff -r 557bd9b5d92f -r e142148d8b54 src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java --- a/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipPath.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/native/java/util/zip/Deflater.c --- a/src/share/native/java/util/zip/Deflater.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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: diff -r 557bd9b5d92f -r e142148d8b54 src/share/native/java/util/zip/Inflater.c --- a/src/share/native/java/util/zip/Inflater.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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; diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/forkjoin/mergesort/MergeDemo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 " + + " "); + 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 iterations number of test sorts of a random array of element 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); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/forkjoin/mergesort/MergeSort.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 job = pool.submit(new MergeSortTask(array, 0, array.length)); + job.join(); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/ChatServer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 connections = Collections.synchronizedList(new ArrayList()); + 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() { + @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 ]"); + 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(); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/Client.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 reader; + private String userName; + private final StringBuilder messageBuffer = new StringBuilder(); + + private final Queue queue = new LinkedList(); + private boolean writing = false; + + public Client(AsynchronousSocketChannel channel, ClientReader reader) { + this.channel = channel; + this.reader = new AtomicReference(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() { + @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 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; + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/ClientReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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() { + @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); + } + }); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/DataReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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(); +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/MessageReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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)); + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/NameReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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]); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 src/share/sample/nio/chatserver/README.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 ] + + 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. diff -r 557bd9b5d92f -r e142148d8b54 src/solaris/bin/java_md.c --- a/src/solaris/bin/java_md.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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); } - } /* diff -r 557bd9b5d92f -r e142148d8b54 src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java --- a/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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); } diff -r 557bd9b5d92f -r e142148d8b54 src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java --- a/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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); } } diff -r 557bd9b5d92f -r e142148d8b54 src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java --- a/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 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")) diff -r 557bd9b5d92f -r e142148d8b54 src/solaris/classes/sun/nio/fs/UnixPath.java --- a/src/solaris/classes/sun/nio/fs/UnixPath.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 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")) diff -r 557bd9b5d92f -r e142148d8b54 src/windows/classes/sun/nio/fs/WindowsPath.java --- a/src/windows/classes/sun/nio/fs/WindowsPath.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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); } diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/com/sun/management/OperatingSystem_md.c --- a/src/windows/native/com/sun/management/OperatingSystem_md.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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 #include #include @@ -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 diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/java/io/WinNTFileSystem_md.c --- a/src/windows/native/java/io/WinNTFileSystem_md.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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 @@ -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; } diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/java/lang/java_props_md.c --- a/src/windows/native/java/lang/java_props_md.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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 = "\\"; diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/sun/management/FileSystemImpl.c --- a/src/windows/native/sun/management/FileSystemImpl.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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); diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c --- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Fri Apr 08 10:31:14 2011 -0700 +++ b/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 @@ -36,6 +36,7 @@ #include #include #include +#include #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()); } diff -r 557bd9b5d92f -r e142148d8b54 src/windows/native/sun/security/provider/WinCAPISeedGenerator.c --- a/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Fri Apr 08 10:31:14 2011 -0700 +++ b/src/windows/native/sun/security/provider/WinCAPISeedGenerator.c Tue Apr 12 14:23:03 2011 -0700 @@ -33,11 +33,6 @@ #include #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; } diff -r 557bd9b5d92f -r e142148d8b54 test/java/lang/Character/CheckScript.java --- a/test/java/lang/Character/CheckScript.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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> 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 + ">"); + } + } + } + } } } diff -r 557bd9b5d92f -r e142148d8b54 test/java/lang/Character/PropertyValueAliases.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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; + +# 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; + +# 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; + +# 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; + +# 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; + +# Ideographic (Ideo) + +Ideo; N ; No ; F ; False +Ideo; Y ; Yes ; T ; True + +# Jamo_Short_Name (JSN) + +# @missing: 0000..10FFFF; Jamo_Short_Name; +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; + +# 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; + +# 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; + +# Name_Alias (Name_Alias) + +# @missing: 0000..10FFFF; Name_Alias; + +# 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; + +# Simple_Lowercase_Mapping (slc) + +# @missing: 0000..10FFFF; Simple_Lowercase_Mapping; + +# Simple_Titlecase_Mapping (stc) + +# @missing: 0000..10FFFF; Simple_Titlecase_Mapping; + +# Simple_Uppercase_Mapping (suc) + +# @missing: 0000..10FFFF; Simple_Uppercase_Mapping; + +# 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; + +# Unicode_1_Name (na1) + +# @missing: 0000..10FFFF; Unicode_1_Name; + +# 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; + +# 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; + +# cjkIICore (cjkIICore) + +# @missing: 0000..10FFFF; cjkIICore; + +# cjkIRG_GSource (cjkIRG_GSource) + +# @missing: 0000..10FFFF; cjkIRG_GSource; + +# cjkIRG_HSource (cjkIRG_HSource) + +# @missing: 0000..10FFFF; cjkIRG_HSource; + +# cjkIRG_JSource (cjkIRG_JSource) + +# @missing: 0000..10FFFF; cjkIRG_JSource; + +# cjkIRG_KPSource (cjkIRG_KPSource) + +# @missing: 0000..10FFFF; cjkIRG_KPSource; + +# cjkIRG_KSource (cjkIRG_KSource) + +# @missing: 0000..10FFFF; cjkIRG_KSource; + +# cjkIRG_MSource (cjkIRG_MSource) + +# @missing: 0000..10FFFF; cjkIRG_MSource; + +# cjkIRG_TSource (cjkIRG_TSource) + +# @missing: 0000..10FFFF; cjkIRG_TSource; + +# cjkIRG_USource (cjkIRG_USource) + +# @missing: 0000..10FFFF; cjkIRG_USource; + +# cjkIRG_VSource (cjkIRG_VSource) + +# @missing: 0000..10FFFF; cjkIRG_VSource; + +# cjkOtherNumeric (cjkOtherNumeric) + +# @missing: 0000..10FFFF; cjkOtherNumeric; NaN + +# cjkPrimaryNumeric (cjkPrimaryNumeric) + +# @missing: 0000..10FFFF; cjkPrimaryNumeric; NaN + +# cjkRSUnicode (cjkRSUnicode) + +# @missing: 0000..10FFFF; cjkRSUnicode; + +# EOF diff -r 557bd9b5d92f -r e142148d8b54 test/java/nio/file/Files/CheckPermissions.java --- a/test/java/nio/file/Files/CheckPermissions.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 -- diff -r 557bd9b5d92f -r e142148d8b54 test/java/nio/file/Files/PassThroughFileSystem.java --- a/test/java/nio/file/Files/PassThroughFileSystem.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/nio/file/Path/Misc.java --- a/test/java/nio/file/Path/Misc.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/EnumMap/DistinctEntrySetElements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 enumMap = new EnumMap<>(TestEnum.class); + + for (TestEnum e : TestEnum.values()) { + enumMap.put(e, e.name()); + } + + Set> entrySet = enumMap.entrySet(); + HashSet> 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."); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/EnumMap/EntrySetIteratorRemoveInvalidatesEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 enumMap = new EnumMap<>(TestEnum.class); + + for (TestEnum e : TestEnum.values()) { + enumMap.put(e, e.name()); + } + + Iterator> entrySetIterator = + enumMap.entrySet().iterator(); + Map.Entry entry = entrySetIterator.next(); + + entrySetIterator.remove(); + + try { + entry.getKey(); + throw new RuntimeException("Test FAILED: Entry not invalidated by removal."); + } catch (Exception e) { } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/EnumMap/SimpleSerialization.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 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; + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/IdentityHashMap/DistinctEntrySetElements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 identityHashMap = + new IdentityHashMap<>(); + + identityHashMap.put("One", "Un"); + identityHashMap.put("Two", "Deux"); + identityHashMap.put("Three", "Trois"); + + Set> entrySet = identityHashMap.entrySet(); + HashSet> 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."); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/IdentityHashMap/EntrySetIteratorRemoveInvalidatesEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 identityHashMap = + new IdentityHashMap<>(); + + identityHashMap.put("One", "Un"); + identityHashMap.put("Two", "Deux"); + identityHashMap.put("Three", "Trois"); + + Iterator> entrySetIterator = + identityHashMap.entrySet().iterator(); + Map.Entry entry = entrySetIterator.next(); + + entrySetIterator.remove(); + + try { + entry.getKey(); + throw new RuntimeException("Test FAILED: Entry not invalidated by removal."); + } catch (Exception e) { } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/PriorityQueue/NoNulls.java --- a/test/java/util/PriorityQueue/NoNulls.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/PriorityQueue/PriorityQueueSort.java --- a/test/java/util/PriorityQueue/PriorityQueueSort.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/Random/DistinctSeeds.java --- a/test/java/util/Random/DistinctSeeds.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/ResourceBundle/Bug4168625Test.java --- a/test/java/util/ResourceBundle/Bug4168625Test.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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"); diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java --- a/test/java/util/concurrent/BlockingQueue/CancelledProducerConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/LoopHelpers.java --- a/test/java/util/concurrent/BlockingQueue/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java --- a/test/java/util/concurrent/BlockingQueue/MultipleProducersSingleConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java --- a/test/java/util/concurrent/BlockingQueue/OfferDrainToLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java --- a/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java --- a/test/java/util/concurrent/BlockingQueue/ProducerConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java --- a/test/java/util/concurrent/BlockingQueue/SingleProducerMultipleConsumerLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentHashMap/DistinctEntrySetElements.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 , + */ + +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 concurrentHashMap = + new ConcurrentHashMap<>(); + + concurrentHashMap.put("One", "Un"); + concurrentHashMap.put("Two", "Deux"); + concurrentHashMap.put("Three", "Trois"); + + Set> entrySet = concurrentHashMap.entrySet(); + HashSet> 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."); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java --- a/test/java/util/concurrent/ConcurrentHashMap/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentHashMap/MapCheck.java --- a/test/java/util/concurrent/ConcurrentHashMap/MapCheck.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentHashMap/MapLoops.java --- a/test/java/util/concurrent/ConcurrentHashMap/MapLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java --- a/test/java/util/concurrent/ConcurrentQueues/ConcurrentQueueLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentQueues/GCRetention.java --- a/test/java/util/concurrent/ConcurrentQueues/GCRetention.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java --- a/test/java/util/concurrent/ConcurrentQueues/IteratorWeakConsistency.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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.*; diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java --- a/test/java/util/concurrent/ConcurrentQueues/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /** diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java --- a/test/java/util/concurrent/ConcurrentQueues/RemovePollRace.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Exchanger/ExchangeLoops.java --- a/test/java/util/concurrent/Exchanger/ExchangeLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Exchanger/LoopHelpers.java --- a/test/java/util/concurrent/Exchanger/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java --- a/test/java/util/concurrent/ExecutorCompletionService/ExecutorCompletionServiceLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java --- a/test/java/util/concurrent/ExecutorCompletionService/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/FutureTask/CancelledFutureLoops.java --- a/test/java/util/concurrent/FutureTask/CancelledFutureLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/FutureTask/LoopHelpers.java --- a/test/java/util/concurrent/FutureTask/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Phaser/Arrive.java --- a/test/java/util/concurrent/Phaser/Arrive.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Phaser/Basic.java --- a/test/java/util/concurrent/Phaser/Basic.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Phaser/FickleRegister.java --- a/test/java/util/concurrent/Phaser/FickleRegister.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Phaser/PhaseOverflow.java --- a/test/java/util/concurrent/Phaser/PhaseOverflow.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Phaser/TieredArriveLoops.java --- a/test/java/util/concurrent/Phaser/TieredArriveLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java --- a/test/java/util/concurrent/ScheduledThreadPoolExecutor/DelayOverflow.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Semaphore/PermitOverflow.java --- a/test/java/util/concurrent/Semaphore/PermitOverflow.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/Semaphore/RacingReleases.java --- a/test/java/util/concurrent/Semaphore/RacingReleases.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/forkjoin/Integrate.java --- a/test/java/util/concurrent/forkjoin/Integrate.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/forkjoin/NQueensCS.java --- a/test/java/util/concurrent/forkjoin/NQueensCS.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java --- a/test/java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java --- a/test/java/util/concurrent/locks/ReentrantLock/LockOncePerThreadLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java --- a/test/java/util/concurrent/locks/ReentrantLock/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java --- a/test/java/util/concurrent/locks/ReentrantLock/SimpleReentrantLockLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java --- a/test/java/util/concurrent/locks/ReentrantLock/TimeoutLockLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java --- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/LoopHelpers.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java --- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/MapLoops.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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/ */ /* diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java --- a/test/java/util/concurrent/locks/ReentrantReadWriteLock/RWMap.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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.*; diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/zip/FlaterCriticalArray.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 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 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");} +} diff -r 557bd9b5d92f -r e142148d8b54 test/java/util/zip/InflaterBufferSize.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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");} +} diff -r 557bd9b5d92f -r e142148d8b54 test/sample/chatserver/ChatTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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, 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 exceptions = Collections.synchronizedList(new ArrayList()); + + 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 exceptions = Collections.synchronizedList(new ArrayList()); + + 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 exceptions = new ArrayList(); + + 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 exceptions = new ArrayList(); + + 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(); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/sample/mergesort/MergeSortTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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!"); + } + } + + +} diff -r 557bd9b5d92f -r e142148d8b54 test/sun/security/krb5/KrbCredSubKey.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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, + }; +} diff -r 557bd9b5d92f -r e142148d8b54 test/sun/security/krb5/auto/KDC.java --- a/test/sun/security/krb5/auto/KDC.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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, diff -r 557bd9b5d92f -r e142148d8b54 test/sun/security/krb5/auto/NoAddresses.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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); + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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"); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/tools/launcher/ExecutionEnvironment.java --- a/test/tools/launcher/ExecutionEnvironment.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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 codeList = new ArrayList(); 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 env = new HashMap(); - 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()); diff -r 557bd9b5d92f -r e142148d8b54 test/tools/launcher/Test7029048.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 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 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 env, + int nLLPComponents, String caseID) { + final boolean want64 = want32 == false; + env.put(ExecutionEnvironment.JLDEBUG_KEY, "true"); + List 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 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); + } + } +} diff -r 557bd9b5d92f -r e142148d8b54 test/tools/launcher/TestHelper.java --- a/test/tools/launcher/TestHelper.java Fri Apr 08 10:31:14 2011 -0700 +++ b/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() { + @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 outputList = new ArrayList(); + List 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 testOutput; + Map env; + Throwable t; - public TestResult(String str, int rv, List oList) { + public TestResult(String str, int rv, List oList, + Map 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(); }