# HG changeset patch # User lana # Date 1425597802 28800 # Node ID 690957fb08621006cdff4da33d0436c4e041d160 # Parent 4f62c57aef4eb7856b8b2d138925c97492b9a6aa# Parent c4467840385788d636cdb075a820aec4d3e20b6b Merge diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/Tools.gmk --- a/jdk/make/Tools.gmk Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/Tools.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -180,6 +180,8 @@ OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \ OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ PROGRAM := fix_empty_sec_hdr_flags)) + + BUILD_TOOLS_JDK += $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) endif $(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) $(COPY_JIMAGE_SERVICE_PROVIDER) @@ -189,4 +191,3 @@ all: java-tools endif # _TOOLS_GMK - diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/copy/Copy-java.desktop.gmk --- a/jdk/make/copy/Copy-java.desktop.gmk Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/copy/Copy-java.desktop.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -100,34 +100,3 @@ TARGETS += $(PSFONTPROPFILE_TARGET_FILES) ################################################################################ -# -# Copy cursor.properties and cursors gif files to LIB_DST_DIR -# -ifneq ($(OPENJDK_TARGET_OS), macosx) - OPENJDK_TARGET_OS_LIB_SRC := $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/conf -else - OPENJDK_TARGET_OS_LIB_SRC := $(JDK_TOPDIR)/src/java.desktop/macosx/conf -endif - -CURSORS_DEST_DIR := $(LIB_DST_DIR)/images/cursors -CURSORS_OPENJDK_TARGET_OS_LIB_SRC := $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/conf/images/cursors - -$(CURSORS_DEST_DIR)/cursors.properties: $(CURSORS_OPENJDK_TARGET_OS_LIB_SRC)/cursors.properties - $(call install-file) - -TARGETS += $(CURSORS_DEST_DIR)/cursors.properties - -CURSORS_LIB_SRC := $(JDK_TOPDIR)/src/java.desktop/share/conf/images/cursors -ifeq ($(OPENJDK_TARGET_OS), windows) - CURSORS_SRC_FILES := $(CURSORS_LIB_SRC)/invalid32x32.gif $(wildcard $(CURSORS_LIB_SRC)/win32_*.gif) -else # OPENJDK_TARGET_OS - CURSORS_SRC_FILES := $(CURSORS_LIB_SRC)/invalid32x32.gif $(wildcard $(CURSORS_LIB_SRC)/motif_*.gif) -endif # OPENJDK_TARGET_OS -CURSORS_TARGET_FILES := $(subst $(CURSORS_LIB_SRC),$(CURSORS_DEST_DIR),$(CURSORS_SRC_FILES)) - -$(CURSORS_DEST_DIR)/%: $(CURSORS_LIB_SRC)/% - $(call install-file) - -TARGETS += $(CURSORS_TARGET_FILES) - -################################################################################ diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/gensrc/Gensrc-java.desktop.gmk --- a/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -66,8 +66,11 @@ PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources endif +PROP_SRC_FILES := $(filter-out %cursors.properties, \ + $(filter %.properties, $(call CacheFind, $(PROP_SRC_DIRS)))) + $(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ - $(filter %.properties, $(call CacheFind, $(PROP_SRC_DIRS))), ListResourceBundle)) + $(PROP_SRC_FILES), ListResourceBundle)) GENSRC_JAVA_DESKTOP += $(COMPILE_PROPERTIES) diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/gensrc/Gensrc-java.management.gmk --- a/jdk/make/gensrc/Gensrc-java.management.gmk Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/gensrc/Gensrc-java.management.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -25,6 +25,9 @@ include GensrcCommon.gmk +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-java.management.gmk)) + ################################################################################ include GensrcProperties.gmk diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/lib/SoundLibraries.gmk --- a/jdk/make/lib/SoundLibraries.gmk Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/lib/SoundLibraries.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -114,38 +114,9 @@ endif # OPENJDK_TARGET_OS solaris -ifeq ($(JVM_VARIANT_ZERO), true) - LIBJSOUND_CFLAGS += -DX_ARCH=X_ZERO -else - ifeq ($(OPENJDK_TARGET_CPU), x86) - LIBJSOUND_CFLAGS += -DX_ARCH=X_I586 - endif - - ifeq ($(OPENJDK_TARGET_CPU), sparc) - LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARC - endif - - ifeq ($(OPENJDK_TARGET_CPU), sparcv9) - LIBJSOUND_CFLAGS += -DX_ARCH=X_SPARCV9 + ifeq ($(OPENJDK_TARGET_CPU), aarch64) + LIBJSOUND_CFLAGS += -DX_ARCH=X_AARCH64 endif - - ifeq ($(OPENJDK_TARGET_CPU), x86_64) - LIBJSOUND_CFLAGS += -DX_ARCH=X_AMD64 - endif - - ifeq ($(OPENJDK_TARGET_CPU), arm) - LIBJSOUND_CFLAGS += -DX_ARCH=X_ARM - endif - - ifeq ($(OPENJDK_TARGET_CPU), ppc) - LIBJSOUND_CFLAGS += -DX_ARCH=X_PPC - endif - - ifeq ($(OPENJDK_TARGET_CPU), ppc64) - LIBJSOUND_CFLAGS += -DX_ARCH=X_PPC64 - endif -endif - LIBJSOUND_CFLAGS += -DEXTRA_SOUND_JNI_LIBS='"$(EXTRA_SOUND_JNI_LIBS)"' $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUND, \ diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/mapfiles/libjsound/mapfile-vers --- a/jdk/make/mapfiles/libjsound/mapfile-vers Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/mapfiles/libjsound/mapfile-vers Thu Mar 05 15:23:22 2015 -0800 @@ -68,7 +68,6 @@ Java_com_sun_media_sound_Platform_nGetExtraLibraries; Java_com_sun_media_sound_Platform_nGetLibraryForFeature; Java_com_sun_media_sound_Platform_nIsBigEndian; - Java_com_sun_media_sound_Platform_nIsSigned8; Java_com_sun_media_sound_PortMixer_nClose; Java_com_sun_media_sound_PortMixer_nControlGetFloatValue; Java_com_sun_media_sound_PortMixer_nControlGetIntValue; diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/src/classes/build/tools/module/boot.modules --- a/jdk/make/src/classes/build/tools/module/boot.modules Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/make/src/classes/build/tools/module/boot.modules Thu Mar 05 15:23:22 2015 -0800 @@ -22,6 +22,7 @@ jdk.hprof.agent jdk.httpserver jdk.jfr +jdk.management.cmm jdk.naming.rmi jdk.sctp jdk.security.auth diff -r 4f62c57aef4e -r 690957fb0862 jdk/make/test/JtregNative.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/test/JtregNative.gmk Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,82 @@ +# +# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +################################################################################ +# This file builds the native component of the JTReg tests for JDK. +# It also covers the test-image part, where the built files are copied to the +# test image. +################################################################################ + +default: all + +include $(SPEC) +include MakeBase.gmk +include TestFilesCompilation.gmk + +################################################################################ +# Targets for building the native tests themselves. +################################################################################ + +# Add more directories here when needed. +BUILD_JDK_JTREG_NATIVE_SRC := \ + $(JDK_TOPDIR)/test/native_sanity \ + # + +BUILD_JDK_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/jdk/jtreg/native + +BUILD_JDK_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/jdk/jtreg + +$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_LIBRARIES, \ + TYPE := LIBRARY, \ + SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \ + OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \ +)) + +$(eval $(call SetupTestFilesCompilation, BUILD_JDK_JTREG_EXECUTABLES, \ + TYPE := PROGRAM, \ + SOURCE_DIRS := $(BUILD_JDK_JTREG_NATIVE_SRC), \ + OUTPUT_DIR := $(BUILD_JDK_JTREG_OUTPUT_DIR), \ +)) + +build-test-jdk-jtreg-native: $(BUILD_JDK_JTREG_LIBRARIES) $(BUILD_JDK_JTREG_EXECUTABLES) + + +################################################################################ +# Targets for building test-image. +################################################################################ + +# Copy to jdk jtreg test image +$(eval $(call SetupCopyFiles,COPY_JDK_JTREG_NATIVE, \ + SRC := $(BUILD_JDK_JTREG_OUTPUT_DIR), \ + DEST := $(TEST_IMAGE_DIR)/jdk/jtreg/native, \ + FILES := $(BUILD_JDK_JTREG_LIBRARIES) $(BUILD_JDK_JTREG_EXECUTABLES), \ + FLATTEN := true)) + +test-image-jdk-jtreg-native: $(COPY_JDK_JTREG_NATIVE) + +all: build-test-jdk-jtreg-native +test-image: test-image-jdk-jtreg-native + +.PHONY: default all build-test-jdk-jtreg-native test-image-jdk-jtreg-native test-image diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/io/ObjectInputStream.java --- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Thu Mar 05 15:23:22 2015 -0800 @@ -40,6 +40,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import static java.io.ObjectStreamClass.processQueue; +import sun.misc.Unsafe; import sun.reflect.misc.ReflectUtil; /** @@ -375,6 +376,7 @@ } if (depth == 0) { vlist.doCallbacks(); + freeze(); } return obj; } finally { @@ -465,6 +467,7 @@ } if (depth == 0) { vlist.doCallbacks(); + freeze(); } return obj; } finally { @@ -2357,6 +2360,26 @@ } } + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + /** + * Performs a "freeze" action, required to adhere to final field semantics. + * + *

This method can be called unconditionally before returning the graph, + * from the topmost readObject call, since it is expected that the + * additional cost of the freeze action is negligible compared to + * reconstituting even the most simple graph. + * + *

Nested calls to readObject do not issue freeze actions because the + * sub-graph returned from a nested call is not guaranteed to be fully + * initialized yet (possible cycles). + */ + private void freeze() { + // Issue a StoreStore|StoreLoad fence, which is at least sufficient + // to provide final-freeze semantics. + UNSAFE.storeFence(); + } + /** * Input stream with two modes: in default mode, inputs data written in the * same format as DataOutputStream; in "block data" mode, inputs data diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/FunctionalInterface.java --- a/jdk/src/java.base/share/classes/java/lang/FunctionalInterface.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/FunctionalInterface.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,7 @@ * @jls 4.3.2. The Class Object * @jls 9.8 Functional Interfaces * @jls 9.4.3 Interface Method Body + * @jls 9.6.4.9 @FunctionalInterface * @since 1.8 */ @Documented diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/Override.java --- a/jdk/src/java.base/share/classes/java/lang/Override.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/Override.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,9 @@ * * @author Peter von der Ahé * @author Joshua Bloch - * @jls 9.6.1.4 @Override + * @jls 8.4.8 Inheritance, Overriding, and Hiding + * @jls 9.4.1 Inheritance and Overriding + * @jls 9.6.4.4 @Override * @since 1.5 */ @Target(ElementType.METHOD) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/SafeVarargs.java --- a/jdk/src/java.base/share/classes/java/lang/SafeVarargs.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/SafeVarargs.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ * @since 1.7 * @jls 4.7 Reifiable Types * @jls 8.4.1 Formal Parameters - * @jls 9.6.3.7 @SafeVarargs + * @jls 9.6.4.7 @SafeVarargs */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/SuppressWarnings.java --- a/jdk/src/java.base/share/classes/java/lang/SuppressWarnings.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/SuppressWarnings.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ * @jls 4.12.2 Variables of Reference Type * @jls 5.1.9 Unchecked Conversion * @jls 5.5.2 Checked Casts and Unchecked Casts - * @jls 9.6.3.5 @SuppressWarnings + * @jls 9.6.4.5 @SuppressWarnings */ @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/annotation/Inherited.java --- a/jdk/src/java.base/share/classes/java/lang/annotation/Inherited.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/annotation/Inherited.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ * * @author Joshua Bloch * @since 1.5 - * @jls 9.6.3.3 @Inherited + * @jls 9.6.4.3 @Inherited */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/annotation/Repeatable.java --- a/jdk/src/java.base/share/classes/java/lang/annotation/Repeatable.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/annotation/Repeatable.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,8 @@ * type for the repeatable annotation type. * * @since 1.8 - * @jls 9.6 Annotation Types - * @jls 9.7 Annotations + * @jls 9.6.3 Repeatable Annotation Types + * @jls 9.7.5 Multiple Annotations of the Same Type */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/annotation/Retention.java --- a/jdk/src/java.base/share/classes/java/lang/annotation/Retention.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/annotation/Retention.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ * * @author Joshua Bloch * @since 1.5 - * @jls 9.6.3.2 @Retention + * @jls 9.6.4.2 @Retention */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/annotation/Target.java --- a/jdk/src/java.base/share/classes/java/lang/annotation/Target.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/annotation/Target.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,6 +72,7 @@ * @since 1.5 * @jls 9.6.4.1 @Target * @jls 9.7.4 Where Annotations May Appear + * @jls 9.7.5 Multiple Annotations of the Same Type */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java Thu Mar 05 15:23:22 2015 -0800 @@ -436,7 +436,7 @@ } private MethodType bindArgumentType(BoundMethodHandle mh, int pos, BasicType bt) { - assert(mh.form == lambdaForm); + assert(mh.form.uncustomize() == lambdaForm); assert(mh.form.names[1+pos].type == bt); assert(BasicType.basicType(mh.type().parameterType(pos)) == bt); return mh.type().dropParameterTypes(pos, pos+1); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/math/BigDecimal.java --- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu Mar 05 15:23:22 2015 -0800 @@ -3740,8 +3740,8 @@ throw new ExceptionInInitializerError(ex); } } - static void setIntCompactVolatile(BigDecimal bd, long val) { - unsafe.putLongVolatile(bd, intCompactOffset, val); + static void setIntCompact(BigDecimal bd, long val) { + unsafe.putLong(bd, intCompactOffset, val); } static void setIntValVolatile(BigDecimal bd, BigInteger val) { @@ -3765,7 +3765,7 @@ throw new java.io.StreamCorruptedException(message); // [all values of scale are now allowed] } - UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal)); + UnsafeHolder.setIntCompact(this, compactValFor(intVal)); } /** diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/math/BigInteger.java --- a/jdk/src/java.base/share/classes/java/math/BigInteger.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java Thu Mar 05 15:23:22 2015 -0800 @@ -4368,11 +4368,11 @@ } static void putSign(BigInteger bi, int sign) { - unsafe.putIntVolatile(bi, signumOffset, sign); + unsafe.putInt(bi, signumOffset, sign); } static void putMag(BigInteger bi, int[] magnitude) { - unsafe.putObjectVolatile(bi, magOffset, magnitude); + unsafe.putObject(bi, magOffset, magnitude); } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/nio/file/Files.java --- a/jdk/src/java.base/share/classes/java/nio/file/Files.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/nio/file/Files.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3427,11 +3427,8 @@ * reflect updates to the directory that occur after returning from this * method. * - *

The returned stream encapsulates a {@link DirectoryStream}. - * If timely disposal of file system resources is required, the - * {@code try}-with-resources construct should be used to ensure that the - * stream's {@link Stream#close close} method is invoked after the stream - * operations are completed. + *

The returned stream contains a reference to an open directory. + * The directory is closed by closing the stream. * *

Operating on a closed stream behaves as if the end of stream * has been reached. Due to read-ahead, one or more elements may be @@ -3442,6 +3439,11 @@ * UncheckedIOException} which will be thrown from the method that caused * the access to take place. * + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open directory is closed + * promptly after the stream's operations have completed. + * * @param dir The path to the directory * * @return The {@code Stream} describing the content of the @@ -3549,18 +3551,19 @@ *

When a security manager is installed and it denies access to a file * (or directory), then it is ignored and not included in the stream. * - *

The returned stream encapsulates one or more {@link DirectoryStream}s. - * If timely disposal of file system resources is required, the - * {@code try}-with-resources construct should be used to ensure that the - * stream's {@link Stream#close close} method is invoked after the stream - * operations are completed. Operating on a closed stream will result in an - * {@link java.lang.IllegalStateException}. + *

The returned stream contains references to one or more open directories. + * The directories are closed by closing the stream. * *

If an {@link IOException} is thrown when accessing the directory * after this method has returned, it is wrapped in an {@link * UncheckedIOException} which will be thrown from the method that caused * the access to take place. * + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open directories are closed + * promptly after the stream's operations have completed. + * * @param start * the starting file * @param maxDepth @@ -3613,12 +3616,13 @@ * * In other words, it visits all levels of the file tree. * - *

The returned stream encapsulates one or more {@link DirectoryStream}s. - * If timely disposal of file system resources is required, the - * {@code try}-with-resources construct should be used to ensure that the - * stream's {@link Stream#close close} method is invoked after the stream - * operations are completed. Operating on a closed stream will result in an - * {@link java.lang.IllegalStateException}. + *

The returned stream contains references to one or more open directories. + * The directories are closed by closing the stream. + * + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open directories are closed + * promptly after the stream's operations have completed. * * @param start * the starting file @@ -3658,18 +3662,19 @@ * returned by {@code walk} method, this method may be more efficient by * avoiding redundant retrieval of the {@code BasicFileAttributes}. * - *

The returned stream encapsulates one or more {@link DirectoryStream}s. - * If timely disposal of file system resources is required, the - * {@code try}-with-resources construct should be used to ensure that the - * stream's {@link Stream#close close} method is invoked after the stream - * operations are completed. Operating on a closed stream will result in an - * {@link java.lang.IllegalStateException}. + *

The returned stream contains references to one or more open directories. + * The directories are closed by closing the stream. * *

If an {@link IOException} is thrown when accessing the directory * after returned from this method, it is wrapped in an {@link * UncheckedIOException} which will be thrown from the method that caused * the access to take place. * + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open directories are closed + * promptly after the stream's operations have completed. + * * @param start * the starting file * @param maxDepth @@ -3725,6 +3730,9 @@ * charset and the same line terminators as specified by {@code * readAllLines} are supported. * + *

The returned stream contains a reference to an open file. The file + * is closed by closing the stream. + * *

After this method returns, then any subsequent I/O exception that * occurs while reading from the file or when a malformed or unmappable byte * sequence is read, is wrapped in an {@link UncheckedIOException} that will @@ -3733,12 +3741,10 @@ * place. In case an {@code IOException} is thrown when closing the file, * it is also wrapped as an {@code UncheckedIOException}. * - *

The returned stream encapsulates a {@link Reader}. If timely - * disposal of file system resources is required, the try-with-resources - * construct should be used to ensure that the stream's - * {@link Stream#close close} method is invoked after the stream operations - * are completed. - * + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open file is closed promptly + * after the stream's operations have completed. * * @param path * the path to the file @@ -3780,12 +3786,20 @@ * decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8} * {@link Charset charset}. * + *

The returned stream contains a reference to an open file. The file + * is closed by closing the stream. + * *

This method works as if invoking it were equivalent to evaluating the * expression: *

{@code
      * Files.lines(path, StandardCharsets.UTF_8)
      * }
* + * @apiNote + * This method must be used within a try-with-resources statement or similar + * control structure to ensure that the stream's open file is closed promptly + * after the stream's operations have completed. + * * @param path * the path to the file * diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/security/cert/X509CertSelector.java --- a/jdk/src/java.base/share/classes/java/security/cert/X509CertSelector.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/security/cert/X509CertSelector.java Thu Mar 05 15:23:22 2015 -0800 @@ -2574,8 +2574,10 @@ } else { if (maxPathLen < basicConstraints) { if (debug != null) { - debug.println("X509CertSelector.match: maxPathLen too small (" - + maxPathLen + " < " + basicConstraints + ")"); + debug.println("X509CertSelector.match: cert's maxPathLen " + + "is less than the min maxPathLen set by " + + "basicConstraints. " + + "(" + maxPathLen + " < " + basicConstraints + ")"); } return false; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/time/Instant.java --- a/jdk/src/java.base/share/classes/java/time/Instant.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/time/Instant.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1229,8 +1229,14 @@ * @throws ArithmeticException if numeric overflow occurs */ public long toEpochMilli() { - long millis = Math.multiplyExact(seconds, 1000); - return millis + nanos / 1000_000; + if (seconds < 0 && nanos > 0) { + long millis = Math.multiplyExact(seconds+1, 1000); + long adjustment = nanos / 1000_000 - 1000; + return millis + adjustment; + } else { + long millis = Math.multiplyExact(seconds, 1000); + return millis + nanos / 1000_000; + } } //----------------------------------------------------------------------- diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/Arrays.java --- a/jdk/src/java.base/share/classes/java/util/Arrays.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/Arrays.java Thu Mar 05 15:23:22 2015 -0800 @@ -4685,6 +4685,14 @@ *

If the generator function throws an exception, it is relayed to * the caller and the array is left in an indeterminate state. * + * @apiNote + * Setting a subrange of an array, using a generator function to compute + * each element, can be written as follows: + *

{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.apply(i));
+     * }
+ * * @param type of elements of the array * @param array array to be initialized * @param generator a function accepting an index and producing the desired @@ -4706,6 +4714,15 @@ * is thrown from {@code parallelSetAll} and the array is left in an * indeterminate state. * + * @apiNote + * Setting a subrange of an array, in parallel, using a generator function + * to compute each element, can be written as follows: + *
{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.apply(i));
+     * }
+ * * @param type of elements of the array * @param array array to be initialized * @param generator a function accepting an index and producing the desired @@ -4725,6 +4742,14 @@ *

If the generator function throws an exception, it is relayed to * the caller and the array is left in an indeterminate state. * + * @apiNote + * Setting a subrange of an array, using a generator function to compute + * each element, can be written as follows: + *

{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsInt(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position @@ -4745,6 +4770,15 @@ * is thrown from {@code parallelSetAll} and the array is left in an * indeterminate state. * + * @apiNote + * Setting a subrange of an array, in parallel, using a generator function + * to compute each element, can be written as follows: + *
{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsInt(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position @@ -4763,6 +4797,14 @@ *

If the generator function throws an exception, it is relayed to * the caller and the array is left in an indeterminate state. * + * @apiNote + * Setting a subrange of an array, using a generator function to compute + * each element, can be written as follows: + *

{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsLong(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position @@ -4783,6 +4825,15 @@ * is thrown from {@code parallelSetAll} and the array is left in an * indeterminate state. * + * @apiNote + * Setting a subrange of an array, in parallel, using a generator function + * to compute each element, can be written as follows: + *
{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsLong(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position @@ -4801,6 +4852,14 @@ *

If the generator function throws an exception, it is relayed to * the caller and the array is left in an indeterminate state. * + * @apiNote + * Setting a subrange of an array, using a generator function to compute + * each element, can be written as follows: + *

{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .forEach(i -> array[i] = generator.applyAsDouble(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position @@ -4821,6 +4880,15 @@ * is thrown from {@code parallelSetAll} and the array is left in an * indeterminate state. * + * @apiNote + * Setting a subrange of an array, in parallel, using a generator function + * to compute each element, can be written as follows: + *
{@code
+     * IntStream.range(startInclusive, endExclusive)
+     *          .parallel()
+     *          .forEach(i -> array[i] = generator.applyAsDouble(i));
+     * }
+ * * @param array array to be initialized * @param generator a function accepting an index and producing the desired * value for that position diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/regex/Matcher.java --- a/jdk/src/java.base/share/classes/java/util/regex/Matcher.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/regex/Matcher.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,16 @@ package java.util.regex; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * An engine that performs match operations on a {@linkplain java.lang.CharSequence @@ -209,6 +218,11 @@ boolean anchoringBounds = true; /** + * Number of times this matcher's state has been modified + */ + int modCount; + + /** * No default constructor. */ Matcher() { @@ -248,11 +262,76 @@ * @since 1.5 */ public MatchResult toMatchResult() { - Matcher result = new Matcher(this.parentPattern, text.toString()); - result.first = this.first; - result.last = this.last; - result.groups = this.groups.clone(); - return result; + return toMatchResult(text.toString()); + } + + private MatchResult toMatchResult(String text) { + return new ImmutableMatchResult(this.first, + this.last, + groupCount(), + this.groups.clone(), + text); + } + + private static class ImmutableMatchResult implements MatchResult { + private final int first; + private final int last; + private final int[] groups; + private final int groupCount; + private final String text; + + ImmutableMatchResult(int first, int last, int groupCount, + int groups[], String text) + { + this.first = first; + this.last = last; + this.groupCount = groupCount; + this.groups = groups; + this.text = text; + } + + @Override + public int start() { + return first; + } + + @Override + public int start(int group) { + if (group < 0 || group > groupCount) + throw new IndexOutOfBoundsException("No group " + group); + return groups[group * 2]; + } + + @Override + public int end() { + return last; + } + + @Override + public int end(int group) { + if (group < 0 || group > groupCount) + throw new IndexOutOfBoundsException("No group " + group); + return groups[group * 2 + 1]; + } + + @Override + public int groupCount() { + return groupCount; + } + + @Override + public String group() { + return group(0); + } + + @Override + public String group(int group) { + if (group < 0 || group > groupCount) + throw new IndexOutOfBoundsException("No group " + group); + if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) + return null; + return text.subSequence(groups[group * 2], groups[group * 2 + 1]).toString(); + } } /** @@ -284,6 +363,7 @@ groups[i] = -1; for (int i = 0; i < locals.length; i++) locals[i] = -1; + modCount++; return this; } @@ -308,6 +388,7 @@ lastAppendPosition = 0; from = 0; to = getTextLength(); + modCount++; return this; } @@ -803,6 +884,7 @@ // Append the match substitution sb.append(result); lastAppendPosition = last; + modCount++; return this; } @@ -892,6 +974,7 @@ // Append the match substitution sb.append(result); lastAppendPosition = last; + modCount++; return this; } @@ -1078,6 +1161,183 @@ } /** + * Replaces every subsequence of the input sequence that matches the + * pattern with the result of applying the given replacer function to the + * match result of this matcher corresponding to that subsequence. + * Exceptions thrown by the function are relayed to the caller. + * + *

This method first resets this matcher. It then scans the input + * sequence looking for matches of the pattern. Characters that are not + * part of any match are appended directly to the result string; each match + * is replaced in the result by the applying the replacer function that + * returns a replacement string. Each replacement string may contain + * references to captured subsequences as in the {@link #appendReplacement + * appendReplacement} method. + * + *

Note that backslashes (\) and dollar signs ($) in + * a replacement string may cause the results to be different than if it + * were being treated as a literal replacement string. Dollar signs may be + * treated as references to captured subsequences as described above, and + * backslashes are used to escape literal characters in the replacement + * string. + * + *

Given the regular expression dog, the input + * "zzzdogzzzdogzzz", and the function + * mr -> mr.group().toUpperCase(), an invocation of this method on + * a matcher for that expression would yield the string + * "zzzDOGzzzDOGzzz". + * + *

Invoking this method changes this matcher's state. If the matcher + * is to be used in further matching operations then it should first be + * reset.

+ * + *

The replacer function should not modify this matcher's state during + * replacement. This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if such modification is + * detected. + * + *

The state of each match result passed to the replacer function is + * guaranteed to be constant only for the duration of the replacer function + * call and only if the replacer function does not modify this matcher's + * state. + * + * @implNote + * This implementation applies the replacer function to this matcher, which + * is an instance of {@code MatchResult}. + * + * @param replacer + * The function to be applied to the match result of this matcher + * that returns a replacement string. + * @return The string constructed by replacing each matching subsequence + * with the result of applying the replacer function to that + * matched subsequence, substituting captured subsequences as + * needed. + * @throws NullPointerException if the replacer function is null + * @throws ConcurrentModificationException if it is detected, on a + * best-effort basis, that the replacer function modified this + * matcher's state + * @since 1.9 + */ + public String replaceAll(Function replacer) { + Objects.requireNonNull(replacer); + reset(); + boolean result = find(); + if (result) { + StringBuilder sb = new StringBuilder(); + do { + int ec = modCount; + String replacement = replacer.apply(this); + if (ec != modCount) + throw new ConcurrentModificationException(); + appendReplacement(sb, replacement); + result = find(); + } while (result); + appendTail(sb); + return sb.toString(); + } + return text.toString(); + } + + /** + * Returns a stream of match results for each subsequence of the input + * sequence that matches the pattern. The match results occur in the + * same order as the matching subsequences in the input sequence. + * + *

Each match result is produced as if by {@link #toMatchResult()}. + * + *

This method does not reset this matcher. Matching starts on + * initiation of the terminal stream operation either at the beginning of + * this matcher's region, or, if the matcher has not since been reset, at + * the first character not matched by a previous match. + * + *

If the matcher is to be used for further matching operations after + * the terminal stream operation completes then it should be first reset. + * + *

This matcher's state should not be modified during execution of the + * returned stream's pipeline. The returned stream's source + * {@code Spliterator} is fail-fast and will, on a best-effort + * basis, throw a {@link java.util.ConcurrentModificationException} if such + * modification is detected. + * + * @return a sequential stream of match results. + * @since 1.9 + */ + public Stream results() { + class MatchResultIterator implements Iterator { + // -ve for call to find, 0 for not found, 1 for found + int state = -1; + // State for concurrent modification checking + // -1 for uninitialized + int expectedCount = -1; + // The input sequence as a string, set once only after first find + // Avoids repeated conversion from CharSequence for each match + String textAsString; + + @Override + public MatchResult next() { + if (expectedCount >= 0 && expectedCount != modCount) + throw new ConcurrentModificationException(); + + if (!hasNext()) + throw new NoSuchElementException(); + + state = -1; + return toMatchResult(textAsString); + } + + @Override + public boolean hasNext() { + if (state >= 0) + return state == 1; + + // Defer throwing ConcurrentModificationException to when next + // or forEachRemaining is called. The is consistent with other + // fail-fast implementations. + if (expectedCount >= 0 && expectedCount != modCount) + return true; + + boolean found = find(); + // Capture the input sequence as a string on first find + if (found && state < 0) + textAsString = text.toString(); + state = found ? 1 : 0; + expectedCount = modCount; + return found; + } + + @Override + public void forEachRemaining(Consumer action) { + if (expectedCount >= 0 && expectedCount != modCount) + throw new ConcurrentModificationException(); + + int s = state; + if (s == 0) + return; + + // Set state to report no more elements on further operations + state = 0; + expectedCount = -1; + + // Perform a first find if required + if (s < 0 && !find()) + return; + + // Capture the input sequence as a string on first find + textAsString = text.toString(); + + do { + int ec = modCount; + action.accept(toMatchResult(textAsString)); + if (ec != modCount) + throw new ConcurrentModificationException(); + } while (find()); + } + } + return StreamSupport.stream(Spliterators.spliteratorUnknownSize( + new MatchResultIterator(), Spliterator.ORDERED | Spliterator.NONNULL), false); + } + + /** * Replaces the first subsequence of the input sequence that matches the * pattern with the given replacement string. * @@ -1123,6 +1383,79 @@ } /** + * Replaces the first subsequence of the input sequence that matches the + * pattern with the result of applying the given replacer function to the + * match result of this matcher corresponding to that subsequence. + * Exceptions thrown by the replace function are relayed to the caller. + * + *

This method first resets this matcher. It then scans the input + * sequence looking for a match of the pattern. Characters that are not + * part of the match are appended directly to the result string; the match + * is replaced in the result by the applying the replacer function that + * returns a replacement string. The replacement string may contain + * references to captured subsequences as in the {@link #appendReplacement + * appendReplacement} method. + * + *

Note that backslashes (\) and dollar signs ($) in + * the replacement string may cause the results to be different than if it + * were being treated as a literal replacement string. Dollar signs may be + * treated as references to captured subsequences as described above, and + * backslashes are used to escape literal characters in the replacement + * string. + * + *

Given the regular expression dog, the input + * "zzzdogzzzdogzzz", and the function + * mr -> mr.group().toUpperCase(), an invocation of this method on + * a matcher for that expression would yield the string + * "zzzDOGzzzdogzzz". + * + *

Invoking this method changes this matcher's state. If the matcher + * is to be used in further matching operations then it should first be + * reset. + * + *

The replacer function should not modify this matcher's state during + * replacement. This method will, on a best-effort basis, throw a + * {@link java.util.ConcurrentModificationException} if such modification is + * detected. + * + *

The state of the match result passed to the replacer function is + * guaranteed to be constant only for the duration of the replacer function + * call and only if the replacer function does not modify this matcher's + * state. + * + * @implNote + * This implementation applies the replacer function to this matcher, which + * is an instance of {@code MatchResult}. + * + * @param replacer + * The function to be applied to the match result of this matcher + * that returns a replacement string. + * @return The string constructed by replacing the first matching + * subsequence with the result of applying the replacer function to + * the matched subsequence, substituting captured subsequences as + * needed. + * @throws NullPointerException if the replacer function is null + * @throws ConcurrentModificationException if it is detected, on a + * best-effort basis, that the replacer function modified this + * matcher's state + * @since 1.9 + */ + public String replaceFirst(Function replacer) { + Objects.requireNonNull(replacer); + reset(); + if (!find()) + return text.toString(); + StringBuilder sb = new StringBuilder(); + int ec = modCount; + String replacement = replacer.apply(this); + if (ec != modCount) + throw new ConcurrentModificationException(); + appendReplacement(sb, replacement); + appendTail(sb); + return sb.toString(); + } + + /** * Sets the limits of this matcher's region. The region is the part of the * input sequence that will be searched to find a match. Invoking this * method resets the matcher, and then sets the region to start at the @@ -1365,6 +1698,7 @@ if (!result) this.first = -1; this.oldLast = this.last; + this.modCount++; return result; } @@ -1387,6 +1721,7 @@ if (!result) this.first = -1; this.oldLast = this.last; + this.modCount++; return result; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/stream/Collectors.java --- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -404,6 +404,54 @@ } /** + * Adapts a {@code Collector} accepting elements of type {@code U} to one + * accepting elements of type {@code T} by applying a flat mapping function + * to each input element before accumulation. The flat mapping function + * maps an input element to a {@link Stream stream} covering zero or more + * output elements that are then accumulated downstream. Each mapped stream + * is {@link java.util.stream.BaseStream#close() closed} after its contents + * have been placed downstream. (If a mapped stream is {@code null} + * an empty stream is used, instead.) + * + * @apiNote + * The {@code flatMapping()} collectors are most useful when used in a + * multi-level reduction, such as downstream of a {@code groupingBy} or + * {@code partitioningBy}. For example, given a stream of + * {@code Order}, to accumulate the set of line items for each customer: + *

{@code
+     *     Map> itemsByCustomerName
+     *         = orders.stream().collect(groupingBy(Order::getCustomerName,
+     *                                              flatMapping(order -> order.getLineItems().stream(), toSet())));
+     * }
+ * + * @param the type of the input elements + * @param type of elements accepted by downstream collector + * @param intermediate accumulation type of the downstream collector + * @param result type of collector + * @param mapper a function to be applied to the input elements, which + * returns a stream of results + * @param downstream a collector which will receive the elements of the + * stream returned by mapper + * @return a collector which applies the mapping function to the input + * elements and provides the flat mapped results to the downstream collector + * @since 1.9 + */ + public static + Collector flatMapping(Function> mapper, + Collector downstream) { + BiConsumer downstreamAccumulator = downstream.accumulator(); + return new CollectorImpl<>(downstream.supplier(), + (r, t) -> { + try (Stream result = mapper.apply(t)) { + if (result != null) + result.sequential().forEach(u -> downstreamAccumulator.accept(r, u)); + } + }, + downstream.combiner(), downstream.finisher(), + downstream.characteristics()); + } + + /** * Adapts a {@code Collector} to perform an additional finishing * transformation. For example, one could adapt the {@link #toList()} * collector to always produce an immutable list with: diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/stream/Stream.java --- a/jdk/src/java.base/share/classes/java/util/stream/Stream.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/stream/Stream.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -126,13 +126,15 @@ * operations may return their receiver rather than a new stream object, it may * not be possible to detect reuse in all cases. * - *

Streams have a {@link #close()} method and implement {@link AutoCloseable}, - * but nearly all stream instances do not actually need to be closed after use. - * Generally, only streams whose source is an IO channel (such as those returned - * by {@link Files#lines(Path, Charset)}) will require closing. Most streams + *

Streams have a {@link #close()} method and implement {@link AutoCloseable}. + * Operating on a stream after it has been closed will throw {@link IllegalStateException}. + * Most stream instances do not actually need to be closed after use, as they * are backed by collections, arrays, or generating functions, which require no - * special resource management. (If a stream does require closing, it can be - * declared as a resource in a {@code try}-with-resources statement.) + * special resource management. Generally, only streams whose source is an IO channel, + * such as those returned by {@link Files#lines(Path)}, will require closing. If a + * stream does require closing, it must be opened as a resource within a try-with-resources + * statement or similar control structure to ensure that it is closed promptly after its + * operations have completed. * *

Stream pipelines may execute either sequentially or in * parallel. This diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipEntry.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,9 @@ class ZipEntry implements ZipConstants, Cloneable { String name; // entry name - long time = -1; // last modification time + long xdostime = -1; // last modification time (in extended DOS time, + // where milliseconds lost in conversion might + // be encoded into the upper half) FileTime mtime; // last modification time, from extra field data FileTime atime; // last access time, from extra field data FileTime ctime; // creation time, from extra field data @@ -64,6 +66,28 @@ public static final int DEFLATED = 8; /** + * DOS time constant for representing timestamps before 1980. + */ + static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16); + + /** + * Approximately 128 years, in milliseconds (ignoring leap years etc). + * + * This establish an approximate high-bound value for DOS times in + * milliseconds since epoch, used to enable an efficient but + * sufficient bounds check to avoid generating extended last modified + * time entries. + * + * Calculating the exact number is locale dependent, would require loading + * TimeZone data eagerly, and would make little practical sense. Since DOS + * times theoretically go to 2107 - with compatibility not guaranteed + * after 2099 - setting this to a time that is before but near 2099 + * should be sufficient. + */ + private static final long UPPER_DOSTIME_BOUND = + 128L * 365 * 24 * 60 * 60 * 1000; + + /** * Creates a new zip entry with the specified name. * * @param name @@ -93,7 +117,7 @@ public ZipEntry(ZipEntry e) { Objects.requireNonNull(e, "entry"); name = e.name; - time = e.time; + xdostime = e.xdostime; mtime = e.mtime; atime = e.atime; ctime = e.ctime; @@ -137,8 +161,14 @@ * @see #getLastModifiedTime() */ public void setTime(long time) { - this.time = time; - this.mtime = null; + this.xdostime = javaToExtendedDosTime(time); + // Avoid setting the mtime field if time is in the valid + // range for a DOS time + if (xdostime != DOSTIME_BEFORE_1980 && time <= UPPER_DOSTIME_BOUND) { + this.mtime = null; + } else { + this.mtime = FileTime.from(time, TimeUnit.MILLISECONDS); + } } /** @@ -158,7 +188,10 @@ * @see #setLastModifiedTime(FileTime) */ public long getTime() { - return time; + if (mtime != null) { + return mtime.toMillis(); + } + return (xdostime != -1) ? extendedDosToJavaTime(xdostime) : -1; } /** @@ -181,7 +214,7 @@ */ public ZipEntry setLastModifiedTime(FileTime time) { this.mtime = Objects.requireNonNull(time, "lastModifiedTime"); - this.time = time.to(TimeUnit.MILLISECONDS); + this.xdostime = javaToExtendedDosTime(time.to(TimeUnit.MILLISECONDS)); return this; } @@ -204,9 +237,9 @@ public FileTime getLastModifiedTime() { if (mtime != null) return mtime; - if (time == -1) + if (xdostime == -1) return null; - return FileTime.from(time, TimeUnit.MILLISECONDS); + return FileTime.from(getTime(), TimeUnit.MILLISECONDS); } /** diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/zip/ZipFile.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ import java.util.stream.StreamSupport; import static java.util.zip.ZipConstants64.*; -import static java.util.zip.ZipUtils.*; /** * This class is used to read entries from a zip file. @@ -567,7 +566,7 @@ e.name = zc.toString(bname, bname.length); } } - e.time = dosToJavaTime(getEntryTime(jzentry)); + e.xdostime = getEntryTime(jzentry); e.crc = getEntryCrc(jzentry); e.size = getEntrySize(jzentry); e.csize = getEntryCSize(jzentry); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/zip/ZipInputStream.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipInputStream.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipInputStream.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -303,7 +303,7 @@ throw new ZipException("encrypted ZIP entry not supported"); } e.method = get16(tmpbuf, LOCHOW); - e.time = dosToJavaTime(get32(tmpbuf, LOCTIM)); + e.xdostime = get32(tmpbuf, LOCTIM); if ((flag & 8) == 8) { /* "Data Descriptor" present */ if (e.method != DEFLATED) { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,6 @@ private static class XEntry { final ZipEntry entry; final long offset; - long dostime; // last modification time in msdos format public XEntry(ZipEntry entry, long offset) { this.entry = entry; this.offset = offset; @@ -192,7 +191,7 @@ if (current != null) { closeEntry(); // close previous entry } - if (e.time == -1) { + if (e.xdostime == -1) { // by default, do NOT use extended timestamps in extra // data, for now. e.setTime(System.currentTimeMillis()); @@ -389,18 +388,12 @@ boolean hasZip64 = false; int elen = getExtraLen(e.extra); - // keep a copy of dostime for writeCEN(), otherwise the tz - // sensitive local time entries in loc and cen might be - // different if the default tz get changed during writeLOC() - // and writeCEN() - xentry.dostime = javaToDosTime(e.time); - writeInt(LOCSIG); // LOC header signature if ((flag & 8) == 8) { writeShort(version(e)); // version needed to extract writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method - writeInt(xentry.dostime); // last modification time + writeInt(e.xdostime); // last modification time // store size, uncompressed size, and crc-32 in data descriptor // immediately following compressed entry data writeInt(0); @@ -415,7 +408,7 @@ } writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method - writeInt(xentry.dostime); // last modification time + writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 if (hasZip64) { writeInt(ZIP64_MAGICVAL); @@ -522,9 +515,7 @@ } writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method - // use the copy in xentry, which has been converted - // from e.time in writeLOC() - writeInt(xentry.dostime); // last modification time + writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 writeInt(csize); // compressed size writeInt(size); // uncompressed size diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java --- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,6 @@ import java.util.Date; import java.util.concurrent.TimeUnit; -import static java.util.zip.ZipConstants.*; -import static java.util.zip.ZipConstants64.*; - class ZipUtils { // used to adjust values between Windows and java epoch @@ -69,7 +66,7 @@ /** * Converts DOS time to Java time (number of milliseconds since epoch). */ - public static long dosToJavaTime(long dtime) { + private static long dosToJavaTime(long dtime) { @SuppressWarnings("deprecation") // Use of date constructor. Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), (int)(((dtime >> 21) & 0x0f) - 1), @@ -81,14 +78,26 @@ } /** + * Converts extended DOS time to Java time, where up to 1999 milliseconds + * might be encoded into the upper half of the returned long. + * + * @param xdostime the extended DOS time value + * @return milliseconds since epoch + */ + public static long extendedDosToJavaTime(long xdostime) { + long time = dosToJavaTime(xdostime); + return time + (xdostime >> 32); + } + + /** * Converts Java time to DOS time. */ @SuppressWarnings("deprecation") // Use of date methods - public static long javaToDosTime(long time) { + private static long javaToDosTime(long time) { Date d = new Date(time); int year = d.getYear() + 1900; if (year < 1980) { - return (1 << 21) | (1 << 16); + return ZipEntry.DOSTIME_BEFORE_1980; } return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | @@ -96,6 +105,23 @@ } /** + * Converts Java time to DOS time, encoding any milliseconds lost + * in the conversion into the upper half of the returned long. + * + * @param time milliseconds since epoch + * @return DOS time with 2s remainder encoded into upper half + */ + public static long javaToExtendedDosTime(long time) { + if (time < 0) { + return ZipEntry.DOSTIME_BEFORE_1980; + } + long dostime = javaToDosTime(time); + return (dostime != ZipEntry.DOSTIME_BEFORE_1980) + ? dostime + ((time % 2000) << 32) + : ZipEntry.DOSTIME_BEFORE_1980; + } + + /** * Fetches unsigned 16-bit value from byte array at specified offset. * The bytes are assumed to be in Intel (little-endian) byte order. */ diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,10 +253,10 @@ String syntax = syntaxAndInput.substring(0, pos); String input = syntaxAndInput.substring(pos + 1); String expr; - if (syntax.equals(GLOB_SYNTAX)) { + if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) { expr = JrtUtils.toRegexPattern(input); } else { - if (syntax.equals(REGEX_SYNTAX)) { + if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) { expr = input; } else { throw new UnsupportedOperationException("Syntax '" + syntax diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -321,12 +321,9 @@ } public void sendUrgentData(int data) throws IOException { - synchronized (sc.blockingLock()) { - if (!sc.isBlocking()) - throw new IllegalBlockingModeException(); - int n = sc.sendOutOfBandData((byte)data); - assert n == 1; - } + int n = sc.sendOutOfBandData((byte) data); + if (n == 0) + throw new IOException("Socket buffer full"); } public void setOOBInline(boolean on) throws SocketException { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AdaptableX509CertSelector.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -224,7 +224,8 @@ if (extVal == null) { if (debug != null) { debug.println("AdaptableX509CertSelector.match: " - + "no subject key ID extension"); + + "no subject key ID extension. Subject: " + + xcert.getSubjectX500Principal()); } return true; } @@ -234,7 +235,9 @@ !Arrays.equals(ski, certSubjectKeyID)) { if (debug != null) { debug.println("AdaptableX509CertSelector.match: " - + "subject key IDs don't match"); + + "subject key IDs don't match. " + + "Expected: " + Arrays.toString(ski) + " " + + "Cert's: " + Arrays.toString(certSubjectKeyID)); } return false; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/Builder.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -435,7 +435,12 @@ if (selector.match(targetCert) && !X509CertImpl.isSelfSigned (targetCert, buildParams.sigProvider())) { if (debug != null) { - debug.println("Builder.addMatchingCerts: adding target cert"); + debug.println("Builder.addMatchingCerts: " + + "adding target cert" + + "\n SN: " + Debug.toHexString( + targetCert.getSerialNumber()) + + "\n Subject: " + targetCert.getSubjectX500Principal() + + "\n Issuer: " + targetCert.getIssuerX500Principal()); } return resultCerts.add(targetCert); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ConstraintsChecker.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,8 +145,8 @@ if (prevNC != null && ((i == certPathLength) || !X509CertImpl.isSelfIssued(currCert))) { if (debug != null) { - debug.println("prevNC = " + prevNC); - debug.println("currDN = " + currCert.getSubjectX500Principal()); + debug.println("prevNC = " + prevNC + + ", currDN = " + currCert.getSubjectX500Principal()); } try { @@ -184,8 +184,8 @@ currCertImpl.getNameConstraintsExtension(); if (debug != null) { - debug.println("prevNC = " + prevNC); - debug.println("newNC = " + String.valueOf(newConstraints)); + debug.println("prevNC = " + prevNC + + ", newNC = " + String.valueOf(newConstraints)); } // if there are no previous name constraints, we just return the @@ -225,8 +225,8 @@ String msg = "basic constraints"; if (debug != null) { debug.println("---checking " + msg + "..."); - debug.println("i = " + i); - debug.println("maxPathLength = " + maxPathLength); + debug.println("i = " + i + + ", maxPathLength = " + maxPathLength); } /* check if intermediate cert */ diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -320,6 +320,14 @@ Set trustAnchors, List certStores, Date validity) throws CRLException, IOException { + if (debug != null) { + debug.println("DistributionPointFetcher.verifyCRL: " + + "checking revocation status for" + + "\n SN: " + Debug.toHexString(certImpl.getSerialNumber()) + + "\n Subject: " + certImpl.getSubjectX500Principal() + + "\n Issuer: " + certImpl.getIssuerX500Principal()); + } + boolean indirectCRL = false; X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl); IssuingDistributionPointExtension idpExt = @@ -363,7 +371,9 @@ } } else if (crlIssuer.equals(certIssuer) == false) { if (debug != null) { - debug.println("crl issuer does not equal cert issuer"); + debug.println("crl issuer does not equal cert issuer.\n" + + "crl issuer: " + crlIssuer + "\n" + + "cert issuer: " + certIssuer); } return false; } else { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,7 +209,8 @@ * getMatchingEECerts */ if (debug != null) { - debug.println("ForwardBuilder.getMatchingCACerts(): ca is target"); + debug.println("ForwardBuilder.getMatchingCACerts(): " + + "the target is a CA"); } if (caTargetSelector == null) { @@ -291,8 +292,14 @@ for (X509Certificate trustedCert : trustedCerts) { if (sel.match(trustedCert)) { if (debug != null) { - debug.println("ForwardBuilder.getMatchingCACerts: " - + "found matching trust anchor"); + debug.println("ForwardBuilder.getMatchingCACerts: " + + "found matching trust anchor." + + "\n SN: " + + Debug.toHexString(trustedCert.getSerialNumber()) + + "\n Subject: " + + trustedCert.getSubjectX500Principal() + + "\n Issuer: " + + trustedCert.getIssuerX500Principal()); } if (caCerts.add(trustedCert) && !searchAllCertStores) { return; diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.StringJoiner; import java.security.cert.CertPath; import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXCertPathChecker; @@ -88,20 +89,25 @@ * current certificate of this loop to be the previous certificate * of the next loop. The state is initialized during first loop. */ - if (debug != null) - debug.println("Checking cert" + (i+1) + " ..."); + X509Certificate currCert = reversedCertList.get(i); - X509Certificate currCert = reversedCertList.get(i); + if (debug != null) { + debug.println("Checking cert" + (i+1) + " - Subject: " + + currCert.getSubjectX500Principal()); + } + Set unresCritExts = currCert.getCriticalExtensionOIDs(); if (unresCritExts == null) { unresCritExts = Collections.emptySet(); } if (debug != null && !unresCritExts.isEmpty()) { - debug.println("Set of critical extensions:"); + StringJoiner joiner = new StringJoiner(", ", "{", "}"); for (String oid : unresCritExts) { - debug.println(oid); + joiner.add(oid); } + debug.println("Set of critical extensions: " + + joiner.toString()); } for (int j = 0; j < certPathCheckers.size(); j++) { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -343,11 +343,17 @@ PublicKey pubKey, boolean crlSignFlag) throws CertPathValidatorException { + if (debug != null) { + debug.println("RevocationChecker.check: checking cert" + + "\n SN: " + Debug.toHexString(xcert.getSerialNumber()) + + "\n Subject: " + xcert.getSubjectX500Principal() + + "\n Issuer: " + xcert.getIssuerX500Principal()); + } try { if (onlyEE && xcert.getBasicConstraints() != -1) { if (debug != null) { - debug.println("Skipping revocation check, not end " + - "entity cert"); + debug.println("Skipping revocation check; cert is not " + + "an end entity cert"); } return; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java --- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,7 +136,8 @@ PKIXCertPathBuilderResult result = buildCertPath(false, adjList); if (result == null) { if (debug != null) { - debug.println("SunCertPathBuilder.engineBuild: 2nd pass"); + debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " + + "try building again searching all certstores"); } // try again adjList.clear(); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,10 @@ */ final class ClientHandshaker extends Handshaker { + // constants for subject alt names of type DNS and IP + private final static int ALTNAME_DNS = 2; + private final static int ALTNAME_IP = 7; + // the server's public key from its certificate. private PublicKey serverKey; @@ -818,6 +822,11 @@ } else { warningSE(Alerts.alert_no_certificate); } + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning: no suitable certificate found - " + + "continuing without client authentication"); + } } // @@ -1497,20 +1506,49 @@ return true; } - // check the iPAddress field in subjectAltName extension - Object thisIPAddress = getSubjectAltName(thisCert, 7); // 7: iPAddress - Object prevIPAddress = getSubjectAltName(prevCert, 7); - if (thisIPAddress != null && prevIPAddress!= null) { - // only allow the exactly match - return Objects.equals(thisIPAddress, prevIPAddress); + // check subject alternative names + Collection> thisSubjectAltNames = null; + try { + thisSubjectAltNames = thisCert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } + } + + Collection> prevSubjectAltNames = null; + try { + prevSubjectAltNames = prevCert.getSubjectAlternativeNames(); + } catch (CertificateParsingException cpe) { + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Attempt to obtain subjectAltNames extension failed!"); + } } - // check the dNSName field in subjectAltName extension - Object thisDNSName = getSubjectAltName(thisCert, 2); // 2: dNSName - Object prevDNSName = getSubjectAltName(prevCert, 2); - if (thisDNSName != null && prevDNSName!= null) { - // only allow the exactly match - return Objects.equals(thisDNSName, prevDNSName); + if ((thisSubjectAltNames != null) && (prevSubjectAltNames != null)) { + // check the iPAddress field in subjectAltName extension + Collection thisSubAltIPAddrs = + getSubjectAltNames(thisSubjectAltNames, ALTNAME_IP); + Collection prevSubAltIPAddrs = + getSubjectAltNames(prevSubjectAltNames, ALTNAME_IP); + if ((thisSubAltIPAddrs != null) && (prevSubAltIPAddrs != null) && + (isEquivalent(thisSubAltIPAddrs, prevSubAltIPAddrs))) { + + return true; + } + + // check the dNSName field in subjectAltName extension + Collection thisSubAltDnsNames = + getSubjectAltNames(thisSubjectAltNames, ALTNAME_DNS); + Collection prevSubAltDnsNames = + getSubjectAltNames(prevSubjectAltNames, ALTNAME_DNS); + if ((thisSubAltDnsNames != null) && (prevSubAltDnsNames != null) && + (isEquivalent(thisSubAltDnsNames, prevSubAltDnsNames))) { + + return true; + } } // check the certificate subject and issuer @@ -1532,28 +1570,39 @@ * Returns the subject alternative name of the specified type in the * subjectAltNames extension of a certificate. */ - private static Object getSubjectAltName(X509Certificate cert, int type) { - Collection> subjectAltNames; + private static Collection getSubjectAltNames( + Collection> subjectAltNames, int type) { - try { - subjectAltNames = cert.getSubjectAlternativeNames(); - } catch (CertificateParsingException cpe) { - if (debug != null && Debug.isOn("handshake")) { - System.out.println( - "Attempt to obtain subjectAltNames extension failed!"); - } - return null; - } - - if (subjectAltNames != null) { - for (List subjectAltName : subjectAltNames) { - int subjectAltNameType = (Integer)subjectAltName.get(0); - if (subjectAltNameType == type) { - return subjectAltName.get(1); + HashSet subAltDnsNames = null; + for (List subjectAltName : subjectAltNames) { + int subjectAltNameType = (Integer)subjectAltName.get(0); + if (subjectAltNameType == type) { + String subAltDnsName = (String)subjectAltName.get(1); + if ((subAltDnsName != null) && !subAltDnsName.isEmpty()) { + if (subAltDnsNames == null) { + subAltDnsNames = + new HashSet<>(subjectAltNames.size()); + } + subAltDnsNames.add(subAltDnsName); } } } - return null; + return subAltDnsNames; + } + + private static boolean isEquivalent(Collection thisSubAltNames, + Collection prevSubAltNames) { + + for (String thisSubAltName : thisSubAltNames) { + for (String prevSubAltName : prevSubAltNames) { + // Only allow the exactly match. Check no wildcard character. + if (thisSubAltName.equalsIgnoreCase(prevSubAltName)) { + return true; + } + } + } + + return false; } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java --- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Mar 05 15:23:22 2015 -0800 @@ -492,11 +492,14 @@ void print(PrintStream s) throws IOException { s.println("*** Certificate chain"); - if (debug != null && Debug.isOn("verbose")) { - for (int i = 0; i < chain.length; i++) + if (chain.length == 0) { + s.println(""); + } else if (debug != null && Debug.isOn("verbose")) { + for (int i = 0; i < chain.length; i++) { s.println("chain [" + i + "] = " + chain[i]); - s.println("***"); + } } + s.println("***"); } X509Certificate[] getCertificateChain() { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Mar 05 15:23:22 2015 -0800 @@ -3790,6 +3790,17 @@ PublicKey pkey, PublicKey akey) throws Exception { + // By design, inside a CertificateExtensions object, all known + // extensions uses name (say, "BasicConstraints") as key and + // a child Extension type (say, "BasicConstraintsExtension") + // as value, unknown extensions uses OID as key and bare + // Extension object as value. This works fine inside JDK. + // + // However, in keytool, there is no way to prevent people + // using OID in -ext, either as a new extension, or in a + // honored value. Thus here we (ab)use CertificateExtensions + // by always using OID as key and value can be of any type. + if (existingEx != null && requestedEx != null) { // This should not happen throw new Exception("One of request and original should be null."); @@ -3805,13 +3816,19 @@ // name{:critical}{=value} // Honoring requested extensions if (requestedEx != null) { + // The existing requestedEx might use names as keys, + // translate to all-OID first. + CertificateExtensions request2 = new CertificateExtensions(); + for (sun.security.x509.Extension ex: requestedEx.getAllExtensions()) { + request2.set(ex.getId(), ex); + } for(String extstr: extstrs) { if (extstr.toLowerCase(Locale.ENGLISH).startsWith("honored=")) { List list = Arrays.asList( extstr.toLowerCase(Locale.ENGLISH).substring(8).split(",")); // First check existence of "all" if (list.contains("all")) { - for (Extension ex: requestedEx.getAllExtensions()) { + for (Extension ex: request2.getAllExtensions()) { setExt(result, ex); } } @@ -3844,7 +3861,7 @@ } String n = findOidForExtName(type).toString(); if (add) { - Extension e = requestedEx.get(n); + Extension e = request2.get(n); if (!e.isCritical() && action == 0 || e.isCritical() && action == 1) { e = Extension.newExtension( diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/native/libjava/Bits.c --- a/jdk/src/java.base/share/native/libjava/Bits.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/native/libjava/Bits.c Thu Mar 05 15:23:22 2015 -0800 @@ -31,24 +31,6 @@ #include "jlong.h" #include -/* - * WARNING: - * - * Do not replace instances of: - * - * if (length > MBYTE) - * size = MBYTE; - * else - * size = length; - * - * with - * - * size = (length > MBYTE ? MBYTE : length); - * - * This expression causes a c compiler assertion failure when compiling on - * 32-bit sparc. - */ - #define MBYTE 1048576 #define GETCRITICAL_OR_RETURN(bytes, env, obj) { \ @@ -71,7 +53,7 @@ ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff))) JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src, +Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; @@ -82,11 +64,7 @@ dstShort = (jshort *)jlong_to_ptr(dstAddr); while (length > 0) { - /* do not change this if-else statement, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); @@ -100,13 +78,12 @@ RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; - dstAddr += size; srcPos += size; } } JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr, +Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; @@ -117,11 +94,7 @@ srcShort = (jshort *)jlong_to_ptr(srcAddr); while (length > 0) { - /* do not change this if-else statement, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); @@ -135,13 +108,12 @@ RELEASECRITICAL(bytes, env, dst, 0); length -= size; - srcAddr += size; dstPos += size; } } JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src, +Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; @@ -152,11 +124,7 @@ dstInt = (jint *)jlong_to_ptr(dstAddr); while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); @@ -170,13 +138,12 @@ RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; - dstAddr += size; srcPos += size; } } JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr, +Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; @@ -187,11 +154,7 @@ srcInt = (jint *)jlong_to_ptr(srcAddr); while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); @@ -205,13 +168,12 @@ RELEASECRITICAL(bytes, env, dst, 0); length -= size; - srcAddr += size; dstPos += size; } } JNIEXPORT void JNICALL -Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src, +Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; @@ -222,11 +184,7 @@ dstLong = (jlong *)jlong_to_ptr(dstAddr); while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); @@ -240,13 +198,12 @@ RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; - dstAddr += size; srcPos += size; } } JNIEXPORT void JNICALL -Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr, +Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; @@ -257,11 +214,7 @@ srcLong = (jlong *)jlong_to_ptr(srcAddr); while (length > 0) { - /* do not change this code, see WARNING above */ - if (length > MBYTE) - size = MBYTE; - else - size = (size_t)length; + size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); @@ -275,7 +228,6 @@ RELEASECRITICAL(bytes, env, dst, 0); length -= size; - srcAddr += size; dstPos += size; } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/share/native/libjava/VM.c --- a/jdk/src/java.base/share/native/libjava/VM.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/share/native/libjava/VM.c Thu Mar 05 15:23:22 2015 -0800 @@ -23,11 +23,8 @@ * questions. */ -#include - #include "jni.h" #include "jni_util.h" -#include "jlong.h" #include "jvm.h" #include "jdk_util.h" @@ -43,12 +40,8 @@ return JVM_LatestUserDefinedLoader(env); } -typedef void (JNICALL *GetJvmVersionInfo_fp)(JNIEnv*, jvm_version_info*, size_t); - JNIEXPORT void JNICALL Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) { - GetJvmVersionInfo_fp func_p; - if (!JDK_InitJvmHandle()) { JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup"); return; @@ -61,15 +54,4 @@ // introducing a Java_sun_misc_VM_getNanoTimeAdjustment wrapper (*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])); - - func_p = (GetJvmVersionInfo_fp) JDK_FindJvmEntry("JVM_GetVersionInfo"); - if (func_p != NULL) { - jvm_version_info info; - - memset(&info, 0, sizeof(info)); - - /* obtain the JVM version info */ - (*func_p)(env, &info, sizeof(info)); - } } - diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java --- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -290,10 +290,10 @@ String input = syntaxAndInput.substring(pos+1); String expr; - if (syntax.equals(GLOB_SYNTAX)) { + if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) { expr = Globs.toUnixRegexPattern(input); } else { - if (syntax.equals(REGEX_SYNTAX)) { + if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) { expr = input; } else { throw new UnsupportedOperationException("Syntax '" + syntax + diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/unix/conf/aarch64/jvm.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/unix/conf/aarch64/jvm.cfg Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,35 @@ +# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# +# List of JVMs that can be used as an option to java, javac, etc. +# Order is important -- first in this list is the default JVM. +# NOTE that this both this file and its format are UNSUPPORTED and +# WILL GO AWAY in a future release. +# +# You may also select a JVM in an arbitrary location with the +# "-XXaltjvm=" option, but that too is unsupported +# and may not be available in a future release. +# +-server KNOWN +-client IGNORE diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java --- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -290,10 +290,10 @@ String input = syntaxAndInput.substring(pos+1); String expr; - if (syntax.equals(GLOB_SYNTAX)) { + if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) { expr = Globs.toWindowsRegexPattern(input); } else { - if (syntax.equals(REGEX_SYNTAX)) { + if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) { expr = input; } else { throw new UnsupportedOperationException("Syntax '" + syntax + diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/windows/native/libjava/TimeZone_md.c --- a/jdk/src/java.base/windows/native/libjava/TimeZone_md.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/windows/native/libjava/TimeZone_md.c Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -195,7 +195,7 @@ * Vista uses the different key name. */ if (ret != ERROR_SUCCESS) { - bufSize = sizeof(val); + bufSize = sizeof(val); ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled", NULL, &valueType, (LPBYTE) &val, &bufSize); } @@ -510,18 +510,49 @@ } else { std_timezone = matchJavaTZ(java_home_dir, result, winZoneName, winMapID); + if (std_timezone == NULL) { + std_timezone = getGMTOffsetID(); + } } } - return std_timezone; } /** - * Returns a GMT-offset-based time zone ID. On Win32, it always return - * NULL since the fall back is performed in getWinTimeZone(). + * Returns a GMT-offset-based time zone ID. */ char * getGMTOffsetID() { - return NULL; + LONG bias = 0; + LONG ret; + HANDLE hKey = NULL; + char zonename[32]; + + // Obtain the current GMT offset value of ActiveTimeBias. + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0, + KEY_READ, (PHKEY)&hKey); + if (ret == ERROR_SUCCESS) { + DWORD val; + DWORD bufSize = sizeof(val); + ULONG valueType = 0; + ret = RegQueryValueExA(hKey, "ActiveTimeBias", + NULL, &valueType, (LPBYTE) &val, &bufSize); + if (ret == ERROR_SUCCESS) { + bias = (LONG) val; + } + (void) RegCloseKey(hKey); + } + + // If we can't get the ActiveTimeBias value, use Bias of TimeZoneInformation. + // Note: Bias doesn't reflect current daylight saving. + if (ret != ERROR_SUCCESS) { + TIME_ZONE_INFORMATION tzi; + if (GetTimeZoneInformation(&tzi) != TIME_ZONE_ID_INVALID) { + bias = tzi.Bias; + } + } + + customZoneName(bias, zonename); + return _strdup(zonename); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c --- a/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Thu Mar 05 15:23:22 2015 -0800 @@ -325,17 +325,14 @@ { BOOL result = 0; HANDLE h = (HANDLE)(handleval(env, fdo)); - LARGE_INTEGER offset; + FILE_END_OF_FILE_INFO eofInfo; - offset.QuadPart = size; - result = SetFilePointerEx(h, offset, NULL, FILE_BEGIN); - if (result == 0) { - JNU_ThrowIOExceptionWithLastError(env, "Truncation failed"); - return IOS_THROWN; - } - - result = SetEndOfFile(h); - if (result == 0) { + eofInfo.EndOfFile.QuadPart = size; + result = SetFileInformationByHandle(h, + FileEndOfFileInfo, + &eofInfo, + sizeof(eofInfo)); + if (result == FALSE) { JNU_ThrowIOExceptionWithLastError(env, "Truncation failed"); return IOS_THROWN; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Thu Mar 05 15:23:22 2015 -0800 @@ -195,7 +195,7 @@ AquaPainter.create(JRSUIState.getInstance()); initIconPainter(painter); - g.setClip(new Rectangle(x, y, width, height)); + g.clipRect(x, y, width, height); painter.paint(g, c, x, y, width, height); g.dispose(); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java --- a/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Thu Mar 05 15:23:22 2015 -0800 @@ -43,7 +43,6 @@ * therefore methods, which is using this id should be ready to it. */ private volatile int displayID; - private volatile Insets screenInsets; private volatile double xResolution; private volatile double yResolution; private volatile int scale; @@ -120,7 +119,13 @@ } public Insets getScreenInsets() { - return screenInsets; + // the insets are queried synchronously and are not cached + // since there are no Quartz or Cocoa means to receive notifications + // on insets changes (e.g. when the Dock is resized): + // the existing CGDisplayReconfigurationCallBack is not notified + // as well as the NSApplicationDidChangeScreenParametersNotification + // is fired on the Dock location changes only + return nativeGetScreenInsets(displayID); } public int getScaleFactor() { @@ -135,7 +140,6 @@ public void displayChanged() { xResolution = nativeGetXResolution(displayID); yResolution = nativeGetYResolution(displayID); - screenInsets = nativeGetScreenInsets(displayID); scale = (int) nativeGetScaleFactor(displayID); //TODO configs/fullscreenWindow/modes? } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h --- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ #import #import -#import -#import #define DEBUG 1 diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp --- a/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ //#define USE_VERBOSE_TRACE #include -#include #include #include #include @@ -617,7 +616,7 @@ ~OSX_DirectAudioDevice() { if (audioUnit) { - CloseComponent(audioUnit); + AudioComponentInstanceDispose(audioUnit); } if (resampler) { delete resampler; @@ -629,17 +628,16 @@ { OSStatus err; AudioUnit unit; - UInt32 size; - ComponentDescription desc; + AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; desc.componentSubType = (deviceID == 0 && isSource) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; - Component comp = FindNextComponent(NULL, &desc); - err = OpenAComponent(comp, &unit); + AudioComponent comp = AudioComponentFindNext(NULL, &desc); + err = AudioComponentInstanceNew(comp, &unit); if (err) { OS_ERROR0(err, "CreateOutputUnit:OpenAComponent"); @@ -664,7 +662,7 @@ // get real AudioDeviceID for default input device (macosx current input device) deviceID = GetDefaultDevice(isSource); if (!deviceID) { - CloseComponent(unit); + AudioComponentInstanceDispose(unit); return NULL; } } @@ -675,7 +673,7 @@ 0, &deviceID, sizeof(deviceID)); if (err) { OS_ERROR0(err, "SetProperty (CurrentDevice)"); - CloseComponent(unit); + AudioComponentInstanceDispose(unit); return NULL; } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/com/sun/media/sound/Platform.java --- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/Platform.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/Platform.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,13 +64,6 @@ // SYSTEM CHARACTERISTICS // vary according to hardware architecture - // signed8 (use signed 8-bit values) is true for everything we support except for - // the solaris sbpro card. - // we'll leave it here as a variable; in the future we may need this in java. - // wait, is that true? i'm not sure. i think solaris takes unsigned data? - // $$kk: 03.11.99: i think solaris takes unsigned 8-bit or signed 16-bit data.... - private static boolean signed8; - // intel is little-endian. sparc is big-endian. private static boolean bigEndian; @@ -110,14 +103,6 @@ } - /** - * Determine whether the system takes signed 8-bit data. - */ - static boolean isSigned8() { - - return signed8; - } - // PRIVATE METHODS /** @@ -185,17 +170,14 @@ // the following native methods are implemented in Platform.c private native static boolean nIsBigEndian(); - private native static boolean nIsSigned8(); private native static String nGetExtraLibraries(); private native static int nGetLibraryForFeature(int feature); - /** * Read the required system properties. */ private static void readProperties() { // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting ! bigEndian = nIsBigEndian(); - signed8 = nIsSigned8(); // Solaris on Sparc: signed, all others unsigned } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/java/awt/Cursor.java --- a/jdk/src/java.desktop/share/classes/java/awt/Cursor.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/java/awt/Cursor.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,18 +24,17 @@ */ package java.awt; -import java.io.File; -import java.io.FileInputStream; - import java.beans.ConstructorProperties; +import java.io.InputStream; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; -import java.security.AccessController; - +import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; -import sun.awt.AWTAccessor; /** * A class to encapsulate the bitmap representation of the mouse cursor. @@ -160,28 +159,19 @@ public static final int CUSTOM_CURSOR = -1; /* - * hashtable, filesystem dir prefix, filename, and properties for custom cursors support + * hashtable, resource prefix, filename, and properties for custom cursors + * support */ - private static final Hashtable systemCustomCursors = new Hashtable<>(1); - private static final String systemCustomCursorDirPrefix = initCursorDir(); - - private static String initCursorDir() { - String jhome = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("java.home")); - return jhome + - File.separator + "lib" + File.separator + "images" + - File.separator + "cursors" + File.separator; - } - - private static final String systemCustomCursorPropertiesFile = systemCustomCursorDirPrefix + "cursors.properties"; + private static final String RESOURCE_PREFIX = "/sun/awt/resources/cursors/"; + private static final String PROPERTIES_FILE = RESOURCE_PREFIX + "cursors.properties"; private static Properties systemCustomCursorProperties = null; - private static final String CursorDotPrefix = "Cursor."; - private static final String DotFileSuffix = ".File"; - private static final String DotHotspotSuffix = ".HotSpot"; - private static final String DotNameSuffix = ".Name"; + private static final String CURSOR_DOT_PREFIX = "Cursor."; + private static final String DOT_FILE_SUFFIX = ".File"; + private static final String DOT_HOTSPOT_SUFFIX = ".HotSpot"; + private static final String DOT_NAME_SUFFIX = ".Name"; /* * JDK 1.1 serialVersionUID @@ -307,8 +297,8 @@ loadSystemCustomCursorProperties(); } - String prefix = CursorDotPrefix + name; - String key = prefix + DotFileSuffix; + String prefix = CURSOR_DOT_PREFIX + name; + String key = prefix + DOT_FILE_SUFFIX; if (!systemCustomCursorProperties.containsKey(key)) { if (log.isLoggable(PlatformLogger.Level.FINER)) { @@ -320,11 +310,10 @@ final String fileName = systemCustomCursorProperties.getProperty(key); - String localized = systemCustomCursorProperties.getProperty(prefix + DotNameSuffix); + final String localized = systemCustomCursorProperties.getProperty( + prefix + DOT_NAME_SUFFIX, name); - if (localized == null) localized = name; - - String hotspot = systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix); + String hotspot = systemCustomCursorProperties.getProperty(prefix + DOT_HOTSPOT_SUFFIX); if (hotspot == null) throw new AWTException("no hotspot property defined for cursor: " + name); @@ -334,31 +323,25 @@ if (st.countTokens() != 2) throw new AWTException("failed to parse hotspot property for cursor: " + name); - int x = 0; - int y = 0; - + final Point hotPoint; try { - x = Integer.parseInt(st.nextToken()); - y = Integer.parseInt(st.nextToken()); + hotPoint = new Point(Integer.parseInt(st.nextToken()), + Integer.parseInt(st.nextToken())); } catch (NumberFormatException nfe) { throw new AWTException("failed to parse hotspot property for cursor: " + name); } try { - final int fx = x; - final int fy = y; - final String flocalized = localized; + final Toolkit toolkit = Toolkit.getDefaultToolkit(); + final String file = RESOURCE_PREFIX + fileName; - cursor = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Cursor run() throws Exception { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - Image image = toolkit.getImage( - systemCustomCursorDirPrefix + fileName); - return toolkit.createCustomCursor( - image, new Point(fx,fy), flocalized); - } - }); + cursor = AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> { + URL url = Cursor.class.getResource(file); + Image image = toolkit.getImage(url); + return toolkit.createCustomCursor(image, hotPoint, + localized); + }); } catch (Exception e) { throw new AWTException( "Exception: " + e.getClass() + " " + e.getMessage() + @@ -452,26 +435,19 @@ systemCustomCursorProperties = new Properties(); try { - AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws Exception { - FileInputStream fis = null; - try { - fis = new FileInputStream( - systemCustomCursorPropertiesFile); - systemCustomCursorProperties.load(fis); - } finally { - if (fis != null) - fis.close(); - } - return null; - } - }); + AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> { + try (InputStream is = Cursor.class + .getResourceAsStream(PROPERTIES_FILE)) { + systemCustomCursorProperties.load(is); + } + return null; + }); } catch (Exception e) { systemCustomCursorProperties = null; throw new AWTException("Exception: " + e.getClass() + " " + e.getMessage() + " occurred while loading: " + - systemCustomCursorPropertiesFile); + PROPERTIES_FILE); } } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java --- a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java Thu Mar 05 15:23:22 2015 -0800 @@ -546,7 +546,7 @@ public float getMinValue(int component) { if ((component < 0) || (component > this.getNumComponents() - 1)) { throw new IllegalArgumentException( - "Component index out of range: + component"); + "Component index out of range: " + component); } return minVal[component]; } @@ -571,7 +571,7 @@ public float getMaxValue(int component) { if ((component < 0) || (component > this.getNumComponents() - 1)) { throw new IllegalArgumentException( - "Component index out of range: + component"); + "Component index out of range: " + component); } return maxVal[component]; } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/javax/swing/JComponent.java --- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Thu Mar 05 15:23:22 2015 -0800 @@ -3763,12 +3763,6 @@ * @param listener the PropertyChangeListener to be added */ public void addPropertyChangeListener(PropertyChangeListener listener) { - if (accessibleContainerHandler == null) { - accessibleContainerHandler = new AccessibleContainerHandler(); - } - if (propertyListenersCount++ == 0) { - JComponent.this.addContainerListener(accessibleContainerHandler); - } super.addPropertyChangeListener(listener); } @@ -3780,9 +3774,6 @@ * @param listener the PropertyChangeListener to be removed */ public void removePropertyChangeListener(PropertyChangeListener listener) { - if (--propertyListenersCount == 0) { - JComponent.this.removeContainerListener(accessibleContainerHandler); - } super.removePropertyChangeListener(listener); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/javax/swing/JMenu.java --- a/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JMenu.java Thu Mar 05 15:23:22 2015 -0800 @@ -476,7 +476,8 @@ } // Then the y: y = s.height + yOffset; // Prefer dropping down - if (position.y + y + pmSize.height >= screenBounds.height && + if (position.y + y + pmSize.height >= screenBounds.height + + screenBounds.y && // popup doesn't fit - place it wherever there's more room screenBounds.height - s.height < 2*(position.y - screenBounds.y)) { diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/javax/swing/JTree.java --- a/jdk/src/java.desktop/share/classes/javax/swing/JTree.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JTree.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -872,11 +872,13 @@ treeModelListener = createTreeModelListener(); if(treeModelListener != null) treeModel.addTreeModelListener(treeModelListener); + // Mark the root as expanded, if it isn't a leaf. - if(treeModel.getRoot() != null && - !treeModel.isLeaf(treeModel.getRoot())) { - expandedState.put(new TreePath(treeModel.getRoot()), - Boolean.TRUE); + Object treeRoot = treeModel.getRoot(); + if(treeRoot != null && + !treeModel.isLeaf(treeRoot)) { + expandedState.put(new TreePath(treeRoot), + Boolean.TRUE); } } firePropertyChange(TREE_MODEL_PROPERTY, oldModel, treeModel); @@ -3000,8 +3002,7 @@ * Expands the root path, assuming the current TreeModel has been set. */ private void expandRoot() { - TreeModel model = getModel(); - + TreeModel model = getModel(); if(model != null && model.getRoot() != null) { expandPath(new TreePath(model.getRoot())); } @@ -3271,9 +3272,12 @@ return null; int count = indexs.length; + Object parent = model.getRoot(); + if (parent == null) + return null; + TreePath parentPath = new TreePath(parent); - for(int counter = 0; counter < count; counter++) { parent = model.getChild(parent, indexs[counter]); if(parent == null) @@ -3860,8 +3864,11 @@ if (parent.getPathCount() == 1) { // New root, remove everything! clearToggledPaths(); - if(treeModel.getRoot() != null && - !treeModel.isLeaf(treeModel.getRoot())) { + + Object treeRoot = treeModel.getRoot(); + + if(treeRoot != null && + !treeModel.isLeaf(treeRoot)) { // Mark the root as expanded, if it isn't a leaf. expandedState.put(parent, Boolean.TRUE); } @@ -4351,7 +4358,12 @@ if (model == null) { return null; } - TreePath path = new TreePath(model.getRoot()); + + Object treeRoot = model.getRoot(); + if (treeRoot == null) { + return null; + } + TreePath path = new TreePath(treeRoot); if (JTree.this.isVisible(path)) { TreeCellRenderer r = JTree.this.getCellRenderer(); TreeUI ui = JTree.this.getUI(); @@ -4364,8 +4376,8 @@ boolean expanded = JTree.this.isExpanded(path); return r.getTreeCellRendererComponent(JTree.this, - model.getRoot(), selected, expanded, - model.isLeaf(model.getRoot()), row, hasFocus); + treeRoot, selected, expanded, + model.isLeaf(treeRoot), row, hasFocus); } } return null; @@ -4418,8 +4430,12 @@ return 1; // the root node } + Object treeRoot = model.getRoot(); + if (treeRoot == null) + return 0; + // return the root's first set of children count - return model.getChildCount(model.getRoot()); + return model.getChildCount(treeRoot); } /** @@ -4433,9 +4449,15 @@ if (model == null) { return null; } + + Object treeRoot = model.getRoot(); + if (treeRoot == null) { + return null; + } + if (isRootVisible()) { if (i == 0) { // return the root node Accessible - Object[] objPath = { model.getRoot() }; + Object[] objPath = { treeRoot }; TreePath path = new TreePath(objPath); return new AccessibleJTreeNode(JTree.this, path, JTree.this); } else { @@ -4444,12 +4466,16 @@ } // return Accessible for one of root's child nodes - int count = model.getChildCount(model.getRoot()); + int count = model.getChildCount(treeRoot); if (i < 0 || i >= count) { return null; } - Object obj = model.getChild(model.getRoot(), i); - Object[] objPath = { model.getRoot(), obj }; + Object obj = model.getChild(treeRoot, i); + if (obj == null) + return null; + + Object[] objPath = {treeRoot, obj }; + TreePath path = new TreePath(objPath); return new AccessibleJTreeNode(JTree.this, path, JTree.this); } @@ -4488,6 +4514,9 @@ public int getAccessibleSelectionCount() { Object[] rootPath = new Object[1]; rootPath[0] = treeModel.getRoot(); + if (rootPath[0] == null) + return 0; + TreePath childPath = new TreePath(rootPath); if (JTree.this.isPathSelected(childPath)) { return 1; @@ -4510,6 +4539,9 @@ if (i == 0) { Object[] rootPath = new Object[1]; rootPath[0] = treeModel.getRoot(); + if (rootPath[0] == null) + return null; + TreePath childPath = new TreePath(rootPath); if (JTree.this.isPathSelected(childPath)) { return new AccessibleJTreeNode(JTree.this, childPath, JTree.this); @@ -4529,6 +4561,9 @@ if (i == 0) { Object[] rootPath = new Object[1]; rootPath[0] = treeModel.getRoot(); + if (rootPath[0] == null) + return false; + TreePath childPath = new TreePath(rootPath); return JTree.this.isPathSelected(childPath); } else { @@ -4549,7 +4584,10 @@ TreeModel model = JTree.this.getModel(); if (model != null) { if (i == 0) { - Object[] objPath = {model.getRoot()}; + Object[] objPath = {model.getRoot()}; + if (objPath[0] == null) + return; + TreePath path = new TreePath(objPath); JTree.this.addSelectionPath(path); } @@ -4568,6 +4606,9 @@ if (model != null) { if (i == 0) { Object[] objPath = {model.getRoot()}; + if (objPath[0] == null) + return; + TreePath path = new TreePath(objPath); JTree.this.removeSelectionPath(path); } @@ -4593,6 +4634,9 @@ TreeModel model = JTree.this.getModel(); if (model != null) { Object[] objPath = {model.getRoot()}; + if (objPath[0] == null) + return; + TreePath path = new TreePath(objPath); JTree.this.addSelectionPath(path); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java --- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java Thu Mar 05 15:23:22 2015 -0800 @@ -377,15 +377,16 @@ } /** - * Creates the appropriate object to represent {@code msg} and - * places it into {@code container}. If {@code msg} is an instance of - * {@code Component}, it is added directly, if it is an {@code Icon}, - * a {@code JLabel} is created to represent it, otherwise a {@code JLabel} is - * created for the string, if {@code d} is an Object[], this method - * will be recursively invoked for the children. {@code internallyCreated} is - * {@code true} if Objc is an instance of {@code Component} and was created - * internally by this method (this is used to correctly set - * {@code hasCustomComponents} only if {@code internallyCreated} is {@code false}). + * Creates the appropriate object to represent {@code msg} and places it + * into {@code container}. If {@code msg} is an instance of + * {@code Component}, it is added directly; if it is an {@code Icon}, a + * {@code JLabel} is created to represent it; otherwise, a {@code JLabel} + * is created for the string. If {@code msg} is an Object[], this method + * will be recursively invoked for the children. {@code internallyCreated} + * is {@code true} if {@code msg} is an instance of {@code Component} and + * was created internally by this method (this is used to correctly set + * {@code hasCustomComponents} only if {@code internallyCreated} is + * {@code false}). * * @param container a container * @param cons an instance of {@code GridBagConstraints} diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java --- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -686,7 +686,12 @@ if (toFocus != null) { if (parent instanceof EmbeddedFrame) { - ((EmbeddedFrame)parent).synthesizeWindowActivation(true); + // JDK-8056915: Try to request focus to the embedder first and + // activate the embedded frame through it + if (!((EmbeddedFrame) parent).requestFocusToEmbedder()) { + // Otherwise activate the embedded frame directly + ((EmbeddedFrame) parent).synthesizeWindowActivation(true); + } } // EmbeddedFrame might have focus before the applet was added. // Thus after its activation the most recent focus owner will be diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java --- a/jdk/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -361,6 +361,15 @@ public void synthesizeWindowActivation(boolean doActivate) {} /** + * Requests the focus to the embedder. + * + * @return {@code true} if focus request was successful, and {@code false} otherwise. + */ + public boolean requestFocusToEmbedder() { + return false; + } + + /** * Moves this embedded frame to a new location. The top-left corner of * the new location is specified by the x and y * parameters relative to the native parent component. diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/CopyDrop32x32.gif Binary file jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/CopyDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/LinkDrop32x32.gif Binary file jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/LinkDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/MoveDrop32x32.gif Binary file jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/MoveDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/cursors.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/cursors.properties Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,40 @@ +# +# +# Cursors Properties file +# +# Names GIF89 sources for Custom Cursors and their associated HotSpots +# +# Note: the syntax of the property name is significant and is parsed +# by java.awt.Cursor +# +# The syntax is: Cursor...File= +# Cursor...HotSpot=, +# Cursor...Name= +# +Cursor.CopyDrop.32x32.File=CopyDrop32x32.gif +Cursor.CopyDrop.32x32.HotSpot=0,0 +Cursor.CopyDrop.32x32.Name=CopyDrop32x32 +# +Cursor.MoveDrop.32x32.File=MoveDrop32x32.gif +Cursor.MoveDrop.32x32.HotSpot=0,0 +Cursor.MoveDrop.32x32.Name=MoveDrop32x32 +# +Cursor.LinkDrop.32x32.File=LinkDrop32x32.gif +Cursor.LinkDrop.32x32.HotSpot=0,0 +Cursor.LinkDrop.32x32.Name=LinkDrop32x32 +# +Cursor.CopyNoDrop.32x32.File=invalid32x32.gif +Cursor.CopyNoDrop.32x32.HotSpot=6,2 +Cursor.CopyNoDrop.32x32.Name=CopyNoDrop32x32 +# +Cursor.MoveNoDrop.32x32.File=invalid32x32.gif +Cursor.MoveNoDrop.32x32.HotSpot=6,2 +Cursor.MoveNoDrop.32x32.Name=MoveNoDrop32x32 +# +Cursor.LinkNoDrop.32x32.File=invalid32x32.gif +Cursor.LinkNoDrop.32x32.HotSpot=6,2 +Cursor.LinkNoDrop.32x32.Name=LinkNoDrop32x32 +# +Cursor.Invalid.32x32.File=invalid32x32.gif +Cursor.Invalid.32x32.HotSpot=6,2 +Cursor.Invalid.32x32.Name=Invalid32x32 diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/invalid32x32.gif Binary file jdk/src/java.desktop/share/classes/sun/awt/resources/cursors/invalid32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/invalid32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/invalid32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_CopyDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_CopyDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_CopyNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_CopyNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_LinkDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_LinkDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_LinkNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_LinkNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_MoveDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_MoveDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/motif_MoveNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/motif_MoveNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_CopyDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_CopyDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_CopyNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_CopyNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_LinkDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_LinkDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_LinkNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_LinkNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_MoveDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_MoveDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/conf/images/cursors/win32_MoveNoDrop32x32.gif Binary file jdk/src/java.desktop/share/conf/images/cursors/win32_MoveNoDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/native/libjsound/Platform.c --- a/jdk/src/java.desktop/share/native/libjsound/Platform.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/native/libjsound/Platform.c Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,19 +40,6 @@ /* * Class: com_sun_media_sound_Platform - * Method: nIsSigned8 - * Signature: ()Z - */ -JNIEXPORT jboolean JNICALL Java_com_sun_media_sound_Platform_nIsSigned8(JNIEnv *env, jclass clss) { -#if ((X_ARCH == X_SPARC) || (X_ARCH == X_SPARCV9)) - return 1; -#else - return 0; -#endif -} - -/* - * Class: com_sun_media_sound_Platform * Method: nGetExtraLibraries * Signature: ()Ljava/lang/String; */ diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/share/native/libjsound/SoundDefs.h --- a/jdk/src/java.desktop/share/native/libjsound/SoundDefs.h Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/share/native/libjsound/SoundDefs.h Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,32 +34,14 @@ #define X_BSD 4 #define X_MACOSX 5 -// types for X_ARCH -#define X_I586 1 -#define X_SPARC 2 -#define X_SPARCV9 3 -#define X_IA64 4 -#define X_AMD64 5 -#define X_ZERO 6 -#define X_ARM 7 -#define X_PPC 8 - +#define X_AARCH64 9 // ********************************** -// Make sure you set X_PLATFORM and X_ARCH defines correctly. +// Make sure you set X_PLATFORM defines correctly. // Everything depends upon this flag being setup correctly. // ********************************** -#if (X_PLATFORM == X_MACOSX) && !defined(X_ARCH) -#if __x86_64__ -#define X_ARCH X_AMD64 -#endif -#if __i386__ -#define X_ARCH X_I586 -#endif -#endif - -#if (!defined(X_PLATFORM) || !defined(X_ARCH)) -#error "You need to define X_PLATFORM and X_ARCH outside of the source. Use the types above." +#if (!defined(X_PLATFORM)) +#error "You need to define X_PLATFORM outside of the source. Use the types above." #endif diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/unix/conf/images/cursors/cursors.properties --- a/jdk/src/java.desktop/unix/conf/images/cursors/cursors.properties Thu Mar 05 11:26:17 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -# -# -# Cursors Properties file -# -# Names GIF89 sources for Custom Cursors and their associated HotSpots -# -# Note: the syntax of the property name is significant and is parsed -# by java.awt.Cursor -# -# The syntax is: Cursor...File= -# Cursor...HotSpot=, -# Cursor...Name= -# -Cursor.CopyDrop.32x32.File=motif_CopyDrop32x32.gif -Cursor.CopyDrop.32x32.HotSpot=0,0 -Cursor.CopyDrop.32x32.Name=CopyDrop32x32 -# -Cursor.MoveDrop.32x32.File=motif_MoveDrop32x32.gif -Cursor.MoveDrop.32x32.HotSpot=0,0 -Cursor.MoveDrop.32x32.Name=MoveDrop32x32 -# -Cursor.LinkDrop.32x32.File=motif_LinkDrop32x32.gif -Cursor.LinkDrop.32x32.HotSpot=0,0 -Cursor.LinkDrop.32x32.Name=LinkDrop32x32 -# -Cursor.CopyNoDrop.32x32.File=motif_CopyNoDrop32x32.gif -Cursor.CopyNoDrop.32x32.HotSpot=6,2 -Cursor.CopyNoDrop.32x32.Name=CopyNoDrop32x32 -# -Cursor.MoveNoDrop.32x32.File=motif_MoveNoDrop32x32.gif -Cursor.MoveNoDrop.32x32.HotSpot=6,2 -Cursor.MoveNoDrop.32x32.Name=MoveNoDrop32x32 -# -Cursor.LinkNoDrop.32x32.File=motif_LinkNoDrop32x32.gif -Cursor.LinkNoDrop.32x32.HotSpot=6,2 -Cursor.LinkNoDrop.32x32.Name=LinkNoDrop32x32 -# -Cursor.Invalid.32x32.File=invalid32x32.gif -Cursor.Invalid.32x32.HotSpot=6,2 -Cursor.Invalid.32x32.Name=Invalid32x32 diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/CopyDrop32x32.gif Binary file jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/CopyDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/LinkDrop32x32.gif Binary file jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/LinkDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/MoveDrop32x32.gif Binary file jdk/src/java.desktop/windows/classes/sun/awt/resources/cursors/MoveDrop32x32.gif has changed diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,6 +52,11 @@ private static int pScale = 0; private static final int MAX_BAND_SIZE = (1024*30); + /** + * This flag is set to {@code true} if this embedded frame is hosted by Internet Explorer. + */ + private boolean isEmbeddedInIE = false; + private static String printScale = AccessController.doPrivileged( new GetPropertyAction("sun.java2d.print.pluginscalefactor")); @@ -244,6 +249,14 @@ } } + @SuppressWarnings("deprecation") + public boolean requestFocusToEmbedder() { + if (isEmbeddedInIE) { + return ((WEmbeddedFramePeer) getPeer()).requestFocusToEmbedder(); + } + return false; + } + public void registerAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {} diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java --- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,4 +78,11 @@ // false on other systems. return !Win32GraphicsEnvironment.isDWMCompositionEnabled(); } + + /** + * Sets the focus to plugin control window, the parent of embedded frame. + * Eventually, it will synthesizeWindowActivation to activate the embedded frame, + * if plugin control window gets the focus. + */ + public native boolean requestFocusToEmbedder(); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/conf/images/cursors/cursors.properties --- a/jdk/src/java.desktop/windows/conf/images/cursors/cursors.properties Thu Mar 05 11:26:17 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -# -# -# Cursors Properties file -# -# Names GIF89 sources for Custom Cursors and their associated HotSpots -# -# Note: the syntax of the property name is significant and is parsed -# by java.awt.Cursor -# -# The syntax is: Cursor...File=win32_ -# Cursor...HotSpot=, -# Cursor...Name= -# -Cursor.CopyDrop.32x32.File=win32_CopyDrop32x32.gif -Cursor.CopyDrop.32x32.HotSpot=0,0 -Cursor.CopyDrop.32x32.Name=CopyDrop32x32 -# -Cursor.MoveDrop.32x32.File=win32_MoveDrop32x32.gif -Cursor.MoveDrop.32x32.HotSpot=0,0 -Cursor.MoveDrop.32x32.Name=MoveDrop32x32 -# -Cursor.LinkDrop.32x32.File=win32_LinkDrop32x32.gif -Cursor.LinkDrop.32x32.HotSpot=0,0 -Cursor.LinkDrop.32x32.Name=LinkDrop32x32 -# -Cursor.CopyNoDrop.32x32.File=win32_CopyNoDrop32x32.gif -Cursor.CopyNoDrop.32x32.HotSpot=6,2 -Cursor.CopyNoDrop.32x32.Name=CopyNoDrop32x32 -# -Cursor.MoveNoDrop.32x32.File=win32_MoveNoDrop32x32.gif -Cursor.MoveNoDrop.32x32.HotSpot=6,2 -Cursor.MoveNoDrop.32x32.Name=MoveNoDrop32x32 -# -Cursor.LinkNoDrop.32x32.File=win32_LinkNoDrop32x32.gif -Cursor.LinkNoDrop.32x32.HotSpot=6,2 -Cursor.LinkNoDrop.32x32.Name=LinkNoDrop32x32 -# -Cursor.Invalid.32x32.File=invalid32x32.gif -Cursor.Invalid.32x32.HotSpot=6,2 -Cursor.Invalid.32x32.Name=Invalid32x32 diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,6 +82,15 @@ HHOOK mouseHook; HHOOK modalHook; }; + + +// Communication with plugin control + +// The value must be the same as in AxControl.h +#define WM_AX_REQUEST_FOCUS_TO_EMBEDDER (WM_USER + 197) + +static bool SetFocusToPluginControl(HWND hwndPlugin); + /************************************************************************ * AwtFrame fields */ @@ -93,6 +102,7 @@ jmethodID AwtFrame::setExtendedStateMID; jmethodID AwtFrame::activateEmbeddingTopLevelMID; +jfieldID AwtFrame::isEmbeddedInIEID; Hashtable AwtFrame::sm_BlockedThreads("AWTBlockedThreads"); @@ -104,6 +114,7 @@ m_parentWnd = NULL; menuBar = NULL; m_isEmbedded = FALSE; + m_isEmbeddedInIE = FALSE; m_isLightweight = FALSE; m_ignoreWmSize = FALSE; m_isMenuDropped = FALSE; @@ -199,6 +210,13 @@ if (isEmbedded) { hwndParent = (HWND)handle; + + // JDK-8056915: Handle focus communication between plugin and frame + frame->m_isEmbeddedInIE = IsEmbeddedInIE(hwndParent); + if (frame->m_isEmbeddedInIE) { + env->SetBooleanField(target, isEmbeddedInIEID, JNI_TRUE); + } + RECT rect; ::GetClientRect(hwndParent, &rect); //Fix for 6328675: SWT_AWT.new_Frame doesn't occupy client area under JDK6 @@ -338,6 +356,21 @@ return frame; } +/* + * Returns true if the frame is embedded into Internet Explorer. + * The function checks the class name of the parent window of the embedded frame. + */ +BOOL AwtFrame::IsEmbeddedInIE(HWND hwndParent) +{ + const char *pluginClass = "Java Plug-in Control Window"; + #define PARENT_CLASS_BUFFER_SIZE 64 + char parentClass[PARENT_CLASS_BUFFER_SIZE]; + + return (::GetClassNameA(hwndParent, parentClass, PARENT_CLASS_BUFFER_SIZE) > 0) + && (strncmp(parentClass, pluginClass, PARENT_CLASS_BUFFER_SIZE) == 0); +} + + LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, MsgRouting &mr) { LRESULT retValue = 0L; @@ -1039,6 +1072,19 @@ if (IsLightweightFrame()) { return TRUE; } + if (isMouseEventCause && IsEmbeddedFrame() && m_isEmbeddedInIE) { + HWND hwndProxy = GetProxyFocusOwner(); + // Do nothing if this frame is focused already + if (::GetFocus() != hwndProxy) { + // Fix for JDK-8056915: + // If window activated with mouse, set focus to plugin control window + // first to preserve focus owner inside browser window + if (SetFocusToPluginControl(::GetParent(GetHWnd()))) { + return TRUE; + } + // Plugin control window is already focused, so do normal processing + } + } return AwtWindow::AwtSetActiveWindow(isMouseEventCause); } @@ -1819,6 +1865,9 @@ AwtFrame::activateEmbeddingTopLevelMID = env->GetMethodID(cls, "activateEmbeddingTopLevel", "()V"); DASSERT(AwtFrame::activateEmbeddingTopLevelMID != NULL); + AwtFrame::isEmbeddedInIEID = env->GetFieldID(cls, "isEmbeddedInIE", "Z"); + DASSERT(AwtFrame::isEmbeddedInIEID != NULL); + CATCH_BAD_ALLOC; } @@ -1911,4 +1960,44 @@ CATCH_BAD_ALLOC; } +JNIEXPORT jboolean JNICALL +Java_sun_awt_windows_WEmbeddedFramePeer_requestFocusToEmbedder(JNIEnv *env, jobject self) +{ + jboolean result = JNI_FALSE; + + TRY; + + AwtFrame *frame = NULL; + + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + frame = (AwtFrame *)pData; + + // JDK-8056915: During initial applet activation, set focus to plugin control window + HWND hwndParent = ::GetParent(frame->GetHWnd()); + + result = SetFocusToPluginControl(hwndParent); + + CATCH_BAD_ALLOC_RET(JNI_FALSE); +ret: + return result; +} + } /* extern "C" */ + +static bool SetFocusToPluginControl(HWND hwndPlugin) +{ + HWND hwndFocus = ::GetFocus(); + + if (hwndFocus == hwndPlugin) { + return false; + } + + ::SetFocus(hwndPlugin); + DWORD dwError = ::GetLastError(); + if (dwError != ERROR_SUCCESS) { + // If direct call failed, use a special message to set focus + return (::SendMessage(hwndPlugin, WM_AX_REQUEST_FOCUS_TO_EMBEDDER, 0, 0) == 0); + } + return true; +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.h --- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.h Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.h Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,9 @@ /* method id for WEmbeddedFrame.requestActivate() method */ static jmethodID activateEmbeddingTopLevelMID; + /* field id for WEmbeddedFrame.isEmbeddedInIE */ + static jfieldID isEmbeddedInIEID; + AwtFrame(); virtual ~AwtFrame(); @@ -171,6 +174,13 @@ /* The frame is an EmbeddedFrame. */ BOOL m_isEmbedded; + /* Fix for JDK-8056915: + The embedded frame must gain focus by setting focus to its parent. */ + BOOL m_isEmbeddedInIE; + + /* Checks whether the frame is embedded in IE */ + static BOOL IsEmbeddedInIE(HWND hwndParent); + /* The frame is a LightweightFrame */ BOOL m_isLightweight; diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java --- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -538,6 +538,13 @@ currentFetchThread = null; } + if (nr == null) { + if (logger.traceOn()) { + logger.trace("NotifFetcher-run", + "Recieved null object as notifs, stops fetching because the " + + "notification server is terminated."); + } + } if (nr == null || shouldStop()) { // tell that the thread is REALLY stopped setState(STOPPED); @@ -657,7 +664,7 @@ return null; } - if (shouldStop()) + if (shouldStop() || nr == null) return null; startSequenceNumber = nr.getNextSequenceNumber(); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java --- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Thu Mar 05 15:23:22 2015 -0800 @@ -1254,10 +1254,11 @@ if (serverTerminated) { // we must not call fetchNotifs() if the server is // terminated (timeout elapsed). - // - return new NotificationResult(0L, 0L, - new TargetedNotification[0]); - + // returns null to force the client to stop fetching + if (logger.debugOn()) logger.debug("fetchNotifications", + "The notification server has been closed, " + + "returns null to force the client to stop fetching"); + return null; } final long csn = clientSequenceNumber; final int mn = maxNotifications; diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -282,6 +282,7 @@ * implemented interface */ ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType(); + if (!declType.isAssignableFrom(this)) { throw new IllegalArgumentException("Invalid method"); } @@ -311,7 +312,7 @@ /* * For nonvirtual invokes, method must have a body */ - if ((options & INVOKE_NONVIRTUAL) != 0) { + if (isNonVirtual(options)) { if (method.isAbstract()) { throw new IllegalArgumentException("Abstract method"); } @@ -323,7 +324,7 @@ * method argument types. */ ClassTypeImpl invokedClass; - if ((options & INVOKE_NONVIRTUAL) != 0) { + if (isNonVirtual(options)) { // No overrides in non-virtual invokes invokedClass = clazz; } else { @@ -348,7 +349,7 @@ /* * Only default methods allowed for nonvirtual invokes */ - if (!method.isDefault()) { + if (isNonVirtual(options) && !method.isDefault()) { throw new IllegalArgumentException("Not a default method"); } } @@ -383,6 +384,7 @@ IncompatibleThreadStateException, InvocationException, ClassNotLoadedException { + validateMirror(threadIntf); validateMirror(methodIntf); validateMirrorsOrNulls(origArguments); @@ -624,4 +626,8 @@ byte typeValueKey() { return JDWP.Tag.OBJECT; } + + private static boolean isNonVirtual(int options) { + return (options & INVOKE_NONVIRTUAL) != 0; + } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/jdk.jdwp.agent/share/native/libjdwp/StringReferenceImpl.c --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/StringReferenceImpl.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/StringReferenceImpl.c Thu Mar 05 15:23:22 2015 -0800 @@ -46,8 +46,10 @@ char *utf; utf = (char *)JNI_FUNC_PTR(env,GetStringUTFChars)(env, string, NULL); - (void)outStream_writeString(out, utf); - JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, string, utf); + if (!(*env)->ExceptionCheck(env)) { + (void)outStream_writeString(out, utf); + JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, string, utf); + } } END_WITH_LOCAL_REFS(env); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c Thu Mar 05 15:23:22 2015 -0800 @@ -98,7 +98,9 @@ /* Create weak reference to make sure we have a reference */ weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, ref); - if (weakRef == NULL) { + // NewWeakGlobalRef can throw OOM, clear exception here. + if ((*env)->ExceptionCheck(env)) { + (*env)->ExceptionClear(env); jvmtiDeallocate(node); return NULL; } @@ -154,6 +156,7 @@ /* * NewGlobalRef on a weak ref will return NULL if the weak * reference has been collected or if out of memory. + * It never throws OOM. * We need to distinguish those two occurrences. */ if ((strongRef == NULL) && !isSameObject(env, node->ref, NULL)) { @@ -178,6 +181,11 @@ jweak weakRef; weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, node->ref); + // NewWeakGlobalRef can throw OOM, clear exception here. + if ((*env)->ExceptionCheck(env)) { + (*env)->ExceptionClear(env); + } + if (weakRef != NULL) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref); node->ref = weakRef; @@ -452,6 +460,7 @@ jobject lref; lref = JNI_FUNC_PTR(env,NewLocalRef)(env, node->ref); + // NewLocalRef never throws OOM. if ( lref == NULL ) { /* Object was GC'd shortly after we found the node */ deleteNodeByID(env, node->seqNum, ALL_REFS); diff -r 4f62c57aef4e -r 690957fb0862 jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 201, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -237,10 +237,10 @@ String syntax = syntaxAndInput.substring(0, pos); String input = syntaxAndInput.substring(pos + 1); String expr; - if (syntax.equals(GLOB_SYNTAX)) { + if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) { expr = toRegexPattern(input); } else { - if (syntax.equals(REGEX_SYNTAX)) { + if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) { expr = input; } else { throw new UnsupportedOperationException("Syntax '" + syntax + diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/Makefile --- a/jdk/test/Makefile Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/Makefile Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -112,6 +112,19 @@ JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS) endif +# jtreg -nativepath +# +# Local make tests will be TEST_IMAGE_DIR and JPRT with jprt.use.reg.test.bundle=true +# should be JPRT_TESTNATIVE_PATH +ifdef TEST_IMAGE_DIR + TESTNATIVE_DIR = $(TEST_IMAGE_DIR) +else ifdef JPRT_TESTNATIVE_PATH + TESTNATIVE_DIR = $(JPRT_TESTNATIVE_PATH) +endif +ifdef TESTNATIVE_DIR + JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/jdk/jtreg/native") +endif + # Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results) ifdef JPRT_ARCHIVE_BUNDLE ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE) @@ -313,6 +326,7 @@ -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport") \ -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork") \ -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \ + $(JTREG_NATIVE_PATH) \ $(JTREG_EXCLUSIONS) \ $(JTREG_TEST_OPTIONS) \ $(TEST_SELECTION) \ diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/TEST.groups --- a/jdk/test/TEST.groups Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/TEST.groups Thu Mar 05 15:23:22 2015 -0800 @@ -168,6 +168,9 @@ jdk_jdi = \ com/sun/jdi +jdk_native_sanity = \ + native_sanity + # java launcher specific tests, Note: do not include this group into any groups # that potentially could be included into a jprt test rule, as the complementary # closed group includes awt SplashScreen and these tests may not run diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/com/sun/crypto/provider/Cipher/JCE/Bugs/4686632/Empty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Cipher/JCE/Bugs/4686632/Empty.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.String; +import javax.crypto.SecretKey; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import static java.lang.System.out; + +/* + * @test + * @bug 4686632 8048610 + * @summary To verify Cipher.init will throw InvalidKeyException with + * Non-empty message when create SecretKeySpec with invalid DES key + * @author Kevin Liu + */ +public class Empty { + public static void main(String[] args) throws Exception { + try { + byte master[] = { + 0, 1, 2, 3, 4 + }; + SecretKey key = new SecretKeySpec(master, "DES"); + Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + throw new RuntimeException("InvalidKeyException not thrown"); + } catch (java.security.InvalidKeyException ike) { + ike.printStackTrace(); + if (ike.getMessage() != null) { + out.println("Status -- Passed"); + } else { + throw new RuntimeException("Error message is not expected when" + + " InvalidKeyException is thrown"); + } + + } + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/com/sun/jdi/InterfaceMethodsTest.java --- a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ /** * @test * @bug 8031195 + * @bug 8071657 * @summary JDI: Add support for static and default methods in interfaces * * @run build TestScaffold VMConnection TargetListener TargetAdapter @@ -38,6 +39,7 @@ private static final int RESULT_A = 1; private static final int RESULT_B = 1; private static final int RESULT_TARGET = 1; + static interface InterfaceA { static int staticMethodA() { System.out.println("-InterfaceA: static interface method A-"); @@ -202,6 +204,9 @@ // try to invoke static method B on the instance testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A)); + + // try to invoke a virtual method + testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true); } private void testInterfaceB(ObjectReference ref) { @@ -302,9 +307,14 @@ private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, String methodSig, Value value) { + testInvokePos(targetClass, ref, methodName, methodSig, value, false); + } + + private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName, + String methodSig, Value value, boolean virtual) { logInvocation(ref, methodName, methodSig, targetClass); try { - invoke(targetClass, ref, methodName, methodSig, value); + invoke(targetClass, ref, methodName, methodSig, value, virtual); System.err.println("--- PASSED"); } catch (Exception e) { System.err.println("--- FAILED"); @@ -314,9 +324,14 @@ private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, String methodSig, Value value, String msg) { + testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false); + } + + private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName, + String methodSig, Value value, String msg, boolean virtual) { logInvocation(ref, methodName, methodSig, targetClass); try { - invoke(targetClass, ref, methodName, methodSig, value); + invoke(targetClass, ref, methodName, methodSig, value, virtual); System.err.println("--- FAILED"); failure("FAILED: " + msg); } catch (Exception e) { @@ -326,7 +341,7 @@ } private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName, - String methodSig, Value value) + String methodSig, Value value, boolean virtual) throws Exception { Method method = getMethod(targetClass, methodName, methodSig); if (method == null) { @@ -334,10 +349,15 @@ } println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method); + println(method.declaringType().toString()); Value returnValue = null; if (ref != null) { - returnValue = invokeInstance(ref, method); + if (virtual) { + returnValue = invokeVirtual(ref, method); + } else { + returnValue = invokeInstance(ref, method); + } } else { returnValue = invokeStatic(targetClass, method); } @@ -362,6 +382,10 @@ return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); } + private Value invokeVirtual(ObjectReference ref, Method method) throws Exception { + return ref.invokeMethod(mainThread, method, Collections.emptyList(), 0); + } + private Value invokeStatic(ReferenceType refType, Method method) throws Exception { if (refType instanceof ClassType) { return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL); diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/awt/Color/GetMinMaxValue_ICC_ColorSpace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Color/GetMinMaxValue_ICC_ColorSpace.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.awt.color.ColorSpace; +import java.awt.color.ICC_ColorSpace; +import java.awt.color.ICC_Profile; +import java.io.IOException; + +/** + * @test + * @bug 8072678 + * @author Prasanta Sadhukhan + */ + +public class GetMinMaxValue_ICC_ColorSpace { + + public static void main(String[] a) throws Exception { + ICC_Profile cmyk_profile = ICC_Profile.getInstance(ColorSpace.CS_sRGB); + ICC_ColorSpace colorSpace = new ICC_ColorSpace(cmyk_profile); + String minstr = null; + String maxstr = null; + + colorSpace.fromRGB(new float[]{4.3f,3.1f,2.2f}); + try { + System.out.println("minvalue " + colorSpace.getMinValue(3)); + } catch (IllegalArgumentException iae) { + minstr = iae.toString(); + } + try { + System.out.println("maxvalue " + colorSpace.getMaxValue(3)); + } catch (IllegalArgumentException iae) { + maxstr = iae.toString(); + } + + if (minstr.endsWith("+ component") || maxstr.endsWith("+ component")) { + System.out.println("Test failed"); + throw new RuntimeException("IllegalArgumentException contains incorrect text message"); + } else { + System.out.println("Test passed"); + } + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/awt/Cursor/GetSystemCustomCursor/GetSystemCustomCursor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Cursor/GetSystemCustomCursor/GetSystemCustomCursor.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.AWTException; +import java.awt.Cursor; + +/** + * @test + * @bug 8039269 + * @author Sergey Bylokhov + */ +public final class GetSystemCustomCursor { + + public static void main(final String[] args) throws AWTException { + // This list is copied from cursors.properties + String[] names = {"CopyDrop.32x32", "MoveDrop.32x32", "LinkDrop.32x32", + "CopyNoDrop.32x32", "MoveNoDrop.32x32", + "LinkNoDrop.32x32", "Invalid.32x32"}; + for (final String name : names) { + if (Cursor.getSystemCustomCursor(name) == null) { + throw new RuntimeException("Cursor is null: " + name); + } + } + System.out.println("Test passed"); + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/io/Serializable/clearHandleTable/ClearHandleTable.java --- a/jdk/test/java/io/Serializable/clearHandleTable/ClearHandleTable.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/io/Serializable/clearHandleTable/ClearHandleTable.java Thu Mar 05 15:23:22 2015 -0800 @@ -30,37 +30,48 @@ import java.io.*; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; public class ClearHandleTable { + private static final int TIMES = 1000; + public static void main(String[] args) throws Exception { final int nreps = 100; ObjectOutputStream oout = new ObjectOutputStream(new ByteArrayOutputStream()); - WeakReference[] refs = new WeakReference[nreps]; + List> refs = new ArrayList<>(nreps); for (int i = 0; i < nreps; i++) { String str = new String("blargh"); oout.writeObject(str); - refs[i] = new WeakReference(str); + refs.add(new WeakReference(str)); } oout.reset(); - exhaustMemory(); + + int count = 0; + for (int i=0; i> itr = refs.iterator(); + while(itr.hasNext()) { + WeakReference ref = itr.next(); + if (ref.get() == null) { + itr.remove(); + } } + if (refs.isEmpty()) + break; + Thread.sleep(20); + count++; + if (count % 10 == 0) + System.out.println("Looping " + count + " times"); } - } - static void exhaustMemory() { - ArrayList blob = new ArrayList(); - try { - for (;;) { - blob.add(new int[0xFFFF]); - } - } catch (OutOfMemoryError e) { + if (!refs.isEmpty()) { + throw new Error("failed to garbage collect object"); } } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/lang/invoke/CustomizedLambdaFormTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/invoke/CustomizedLambdaFormTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +/* @test + * @summary Assertion in LambdaFormEditor.bindArgumentType is too strong + * + * @run main/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest + */ +public class CustomizedLambdaFormTest { + + static void testExtendCustomizedBMH() throws Exception { + // Construct BMH + MethodHandle mh = MethodHandles.Lookup.IMPL_LOOKUP.findVirtual(String.class, "concat", + MethodType.methodType(String.class, String.class)) + .bindTo("a"); + mh.customize(); + mh.bindTo("b"); // Try to extend customized BMH + } + + public static void main(String[] args) throws Throwable { + testExtendCustomizedBMH(); + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/nio/channels/SocketChannel/OutOfBand.java --- a/jdk/test/java/nio/channels/SocketChannel/OutOfBand.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/nio/channels/SocketChannel/OutOfBand.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,6 @@ test1(sc1, sc2); test2(sc1, sc2); test3(sc1, sc2); - test4(sc1); - } finally { if (sc1 != null) sc1.close(); if (sc2 != null) sc2.close(); @@ -175,17 +173,4 @@ thr.join(); } - - static void test4(SocketChannel sc) throws IOException { - boolean blocking = sc.isBlocking(); - sc.configureBlocking(false); - try { - sc.socket().sendUrgentData(0); - throw new RuntimeException("IllegalBlockingModeException expected"); - } catch (IllegalBlockingModeException x) { - // expected - } finally { - sc.configureBlocking(blocking); - } - } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/nio/channels/SocketChannel/SendUrgentData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/nio/channels/SocketChannel/SendUrgentData.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8071599 + * @run main/othervm SendUrgentData + * @run main/othervm SendUrgentData -inline + * @summary Test sending of urgent data. + */ + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +public class SendUrgentData { + + /** + * The arguments may be one of the following: + *
    + *
  1. -server
  2. + *
  3. -client host port [-inline]
  4. + *
  5. [-inline]
  6. + *
+ * The first option creates a standalone server, the second a standalone + * client, and the third a self-contained server-client pair on the + * local host. + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + + ServerSocketChannelThread serverThread + = new ServerSocketChannelThread("SendUrgentDataServer"); + serverThread.start(); + boolean b = serverThread.isAlive(); + + String host = null; + int port = 0; + boolean inline = false; + if (args.length > 0 && args[0].equals("-server")) { + System.out.println(serverThread.getAddress()); + Thread.currentThread().suspend(); + } else { + if (args.length > 0 && args[0].equals("-client")) { + host = args[1]; + port = Integer.parseInt(args[2]); + if (args.length > 3) { + inline = args[2].equals("-inline"); + } + } else { + host = "localhost"; + port = serverThread.getAddress().getPort(); + if (args.length > 0) { + inline = args[0].equals("-inline"); + } + } + } + + System.out.println("OOB Inline : "+inline); + + SocketAddress sa = new InetSocketAddress(host, port); + + try (SocketChannel sc = SocketChannel.open(sa)) { + sc.configureBlocking(false); + sc.socket().setOOBInline(inline); + + sc.socket().sendUrgentData(0); + System.out.println("wrote 1 OOB byte"); + + ByteBuffer bb = ByteBuffer.wrap(new byte[100 * 1000]); + + int blocked = 0; + long total = 0; + + int n; + do { + n = sc.write(bb); + if (n == 0) { + System.out.println("blocked, wrote " + total + " so far"); + if (++blocked == 10) { + break; + } + Thread.sleep(100); + } else { + total += n; + bb.rewind(); + } + } while (n > 0); + + long attempted = 0; + while (attempted < total) { + bb.rewind(); + n = sc.write(bb); + System.out.println("wrote " + n + " normal bytes"); + attempted += bb.capacity(); + + String osName = System.getProperty("os.name").toLowerCase(); + + try { + sc.socket().sendUrgentData(0); + } catch (IOException ex) { + if (osName.contains("linux")) { + if (!ex.getMessage().contains("Socket buffer full")) { + throw new RuntimeException("Unexpected message", ex); + } + } else if (osName.contains("os x") || osName.contains("mac")) { + if (!ex.getMessage().equals("No buffer space available")) { + throw new RuntimeException("Unexpected message", ex); + } + } else if (osName.contains("windows")) { + if (!(ex instanceof SocketException)) { + throw new RuntimeException("Unexpected exception", ex); + } else if (!ex.getMessage().contains("Resource temporarily unavailable")) { + throw new RuntimeException("Unexpected message", ex); + } + } else { + throw new RuntimeException("Unexpected IOException", ex); + } + } + + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + // don't want to fail on this so just print trace and break + ex.printStackTrace(); + break; + } + } + } finally { + serverThread.close(); + } + } + + static class ServerSocketChannelThread extends Thread { + + private ServerSocketChannel ssc; + + private ServerSocketChannelThread(String name) { + super(name); + try { + ssc = ServerSocketChannel.open(); + ssc.bind(new InetSocketAddress((0))); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + public void run() { + while (ssc.isOpen()) { + try { + Thread.sleep(100); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + } + try { + ssc.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + System.out.println("ServerSocketChannelThread exiting ..."); + } + + public InetSocketAddress getAddress() throws IOException { + if (ssc == null) { + throw new IllegalStateException("ServerSocketChannel not created"); + } + + return (InetSocketAddress) ssc.getLocalAddress(); + } + + public void close() { + try { + ssc.close(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/nio/file/PathMatcher/Basic.java --- a/jdk/test/java/nio/file/PathMatcher/Basic.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/nio/file/PathMatcher/Basic.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6866397 + * @bug 4313887 6866397 8073445 * @summary Unit test for java.nio.file.PathMatcher */ @@ -173,6 +173,31 @@ System.out.println(" OKAY"); } + // GLOB_SYNTAX case sensitivity of getPathMatcher: should not throw UOE + try { + FileSystems.getDefault().getPathMatcher("glob:java"); + FileSystems.getDefault().getPathMatcher("Glob:java"); + FileSystems.getDefault().getPathMatcher("GLOB:java"); + System.out.println("Test GLOB_SYNTAX case sensitivity OKAY"); + } catch (UnsupportedOperationException e) { + System.err.println("getPathMatcher GLOB_SYNTAX case sensitivity"); + e.printStackTrace(); + failures++; + } + + // REGEX_SYNTAX case sensitivity of getPathMatcher: should not throw UOE + try { + FileSystems.getDefault().getPathMatcher("regex:java"); + FileSystems.getDefault().getPathMatcher("Regex:java"); + FileSystems.getDefault().getPathMatcher("RegEx:java"); + FileSystems.getDefault().getPathMatcher("REGEX:java"); + System.out.println("Test REGEX_SYNTAX case sensitivity OKAY"); + } catch (UnsupportedOperationException e) { + System.err.println("getPathMatcher REGEX_SYNTAX case sensitivity"); + e.printStackTrace(); + failures++; + } + if (failures > 0) throw new RuntimeException(failures + " sub-test(s) failed - see log for details"); diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/rmi/testlibrary/TestLibrary.java --- a/jdk/test/java/rmi/testlibrary/TestLibrary.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/rmi/testlibrary/TestLibrary.java Thu Mar 05 15:23:22 2015 -0800 @@ -413,6 +413,16 @@ } /** + * Creates an RMI {@link Registry} on an ephemeral port. + * + * @returns an RMI Registry + * @throws RemoteException if there was a problem creating a Registry. + */ + public static Registry createRegistryOnEphemeralPort() throws RemoteException { + return LocateRegistry.createRegistry(0); + } + + /** * Returns the port number the RMI {@link Registry} is running on. * * @param registry the registry to find the port of. diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java --- a/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java Thu Mar 05 15:23:22 2015 -0800 @@ -58,7 +58,6 @@ public class PinClientSocketFactory { - private static final int PORT = TestLibrary.getUnusedRandomPort(); private static final int SESSIONS = 50; public interface Factory extends Remote { @@ -96,10 +95,13 @@ } UnicastRemoteObject.unexportObject(factoryImpl, true); - Registry registryImpl = LocateRegistry.createRegistry(PORT); + Registry registryImpl = TestLibrary.createRegistryOnEphemeralPort(); + int port = TestLibrary.getRegistryPort(registryImpl); + System.out.println("Registry listening on port " + port); + CSF csf = new CSF(); Reference registryRef = new WeakReference(csf); - Registry registryStub = LocateRegistry.getRegistry("", PORT, csf); + Registry registryStub = LocateRegistry.getRegistry("", port, csf); csf = null; registryStub.list(); registryStub = null; diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/security/MessageDigest/TestSameLength.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/MessageDigest/TestSameLength.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.Random; + +/** + * @test + * @bug 8050371 + * @summary Check md.getDigestLength() equal digest output length with various + * algorithm/dataLen/(update,digest methods). + * @author Kevin Liu + */ + +public class TestSameLength { + + public static void main(String[] args) throws Exception { + TestSameLength test = new TestSameLength(); + test.run(); + } + + private void run() throws Exception { + String[] algorithmArr = { + "SHA", "Sha", "SHA-1", "sha-1", "SHA1", "sha1", "MD5", "md5", + "SHA-224", "SHA-256", "SHA-384", "SHA-512" + }; + int[] nUpdatesArr = { + 0, 1, 2, 3 + }; + int[] dataLenArr = { + 1, 50, 2500, 125000, 6250000 + }; + + for (String algorithm: algorithmArr) { + for (UpdateMethod update: UpdateMethod.values()) { + for (int dataLen: dataLenArr) { + if (!runTest(algorithm, dataLen, update)) { + throw new RuntimeException( + "Test failed at algorithm/dataLen/numUpdate:" + + algorithm + "/" + dataLen + "/" + + update.toString()); + } + } + } + } + + out.println("All " + algorithmArr.length * nUpdatesArr.length + * dataLenArr.length + " tests Passed"); + } + + private boolean runTest(String algo, long dataLen, + UpdateMethod whichUpdate) throws Exception { + try { + // Do initialization + byte[] data = new byte[(int) dataLen]; + new Random().nextBytes(data); + MessageDigest md = MessageDigest.getInstance(algo); + int outputLen = md.getDigestLength(); + + // Perform the update using all available/possible update methods + whichUpdate.updateDigest(data, md, dataLen); + // Get the output + byte[] output = md.digest(); + + // Compare input and output + return outputLen == output.length; + } catch (Exception ex) { + System.err.println("Testing: " + algo + "/" + dataLen + "/" + + whichUpdate.toString() + + " failed with unexpected exception"); + ex.printStackTrace(); + throw ex; + } + } + + private static enum UpdateMethod { + UPDATE_BYTE { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + for (int i = 0; i < dataLen; i++) { + md.update(data[i]); + } + } + }, + + UPDATE_BUFFER { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + md.update(data); + } + }, + + UPDATE_BUFFER_LEN { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + for (int i = 0; i < dataLen; i++) { + md.update(data, i, 1); + } + } + }, + + UPDATE_BYTE_BUFFER { + @Override + public void updateDigest(byte[] data, + MessageDigest md, long dataLen) { + + md.update(ByteBuffer.wrap(data)); + } + }; + + public abstract void updateDigest(byte[] data, + MessageDigest md, long dataLen); + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/security/MessageDigest/TestSameValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/MessageDigest/TestSameValue.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.System.out; + +import java.nio.ByteBuffer; +import java.security.DigestException; +import java.security.MessageDigest; +import java.util.Random; + +/** + * @test + * @bug 8050371 + * @summary Check md.digest(data) value whether same with digest output value + * with various update/digest methods. + * @author Kevin Liu + */ + +public class TestSameValue { + + public static void main(String[] args) throws Exception { + TestSameValue test1 = new TestSameValue(); + test1.run(); + } + + private void run() throws Exception { + + byte[] data = new byte[6706]; + MessageDigest md = null; + // Initialize input data + new Random().nextBytes(data); + + String[] providers = { + null, "SUN" + }; + String[] algorithmArr = { + "SHA", "Sha", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384", + "SHA-512" + }; + + for (String algorithm: algorithmArr) { + for (String provider: providers) { + if (provider != null) { + md = MessageDigest.getInstance(algorithm, provider); + } else { + md = MessageDigest.getInstance(algorithm); + } + for (UpdateDigestMethod updateMethod: UpdateDigestMethod + .values()) { + byte[] output = updateMethod.updateDigest(data, md); + // Get the output and the "correct" one + byte[] standard = md.digest(data); + // Compare input and output + if (!MessageDigest.isEqual(output, standard)) { + throw new RuntimeException( + "Test failed at algorithm/provider/numUpdate:" + + algorithm + "/" + provider + "/" + + updateMethod); + } + } + } + } + + out.println("All " + algorithmArr.length + * UpdateDigestMethod.values().length * providers.length + + " tests Passed"); + } + + private static enum UpdateDigestMethod { + + /* + * update the data one by one using method update(byte input) then + * do digest (giving the output buffer, offset, and the number of + * bytes to put in the output buffer) + */ + UPDATE_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + for (byte element: data) { + md.update(element); + } + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + /* + * update the data one by one using method update(byte input) + * then do digest + */ + UPDATE_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + for (byte element: data) { + md.update(element); + } + return md.digest(); + } + }, + + /* + * update all the data at once as a block, then do digest ( giving the + * output buffer, offset, and the number of bytes to put in the output + * buffer) + */ + UPDATE_BLOCK_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + md.update(data); + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + // update all the data at once as a block, then do digest + UPDATE_BLOCK_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + md.update(data); + return md.digest(); + } + }, + + /* + * update the leading bytes (length is "data.length-LASTNBYTES") + * at once as a block, then do digest (do a final update using + * the left LASTNBYTES bytes which is passed as a parameter for + * the digest method, then complete the digest) + */ + UPDATE_LEADING_BLOCK_DIGEST_REMAIN { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + byte[] mainPart = new byte[data.length - LASTNBYTES]; + for (int i = 0; i < mainPart.length; i++) { + mainPart[i] = data[i]; + } + for (int j = 0; j < LASTNBYTES; j++) { + REMAIN[j] = data[data.length - LASTNBYTES + j]; + } + md.update(mainPart); + return md.digest(REMAIN); + } + }, + + /* + * update the data 2 bytes each time, after finishing updating, + * do digest (giving the output buffer, offset, and the number + * of bytes to put in the output buffer) + */ + UPDATE_BYTES_DIGEST_BUFFER { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) + throws DigestException { + + for (int i = 0; i < data.length / 2; i++) { + md.update(data, i * 2, 2); + } + byte[] output = new byte[md.getDigestLength()]; + int len = md.digest(output, 0, output.length); + if (len != output.length) { + throw new RuntimeException( + "ERROR" + ": digest length differs!"); + } + return output; + } + }, + + /* + * update the data 2 bytes each time, after finishing updating, + * do digest + */ + UPDATE_BYTES_DIGEST { + @Override + public byte[] updateDigest(byte[] data, MessageDigest md) { + for (int i=0;i { + try { + AccessController.checkPermission(perm); + return (Boolean) false; + } catch (AccessControlException ex) { + return (Boolean) true; + } + }); + + if (expectException ^ getException) { + String message = "Check Permission :" + perm + "\n ExpectException = " + + expectException + "\n getException = " + getException; + throw new RuntimeException(message); + } + + } + +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/security/Policy/SignedJar/SignedJarTest_1.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Policy/SignedJar/SignedJarTest_1.policy Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,10 @@ +keystore "file:both.jks"; +keystorePasswordURL "file:keypass"; + +grant signedBy "first" { + permission java.lang.RuntimePermission "setIO"; +}; + +grant signedBy "second" { + permission java.lang.RuntimePermission "setFactory"; +}; diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/security/Policy/SignedJar/SignedJarTest_2.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Policy/SignedJar/SignedJarTest_2.policy Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,11 @@ +keystore "file:first.jks"; +keystorePasswordURL "file:keypass"; + +grant signedBy "first" { + permission java.lang.RuntimePermission "setIO"; +}; + +grant signedBy "second" { + permission java.lang.RuntimePermission "setFactory"; +}; + diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/security/Policy/SignedJar/keypass --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/Policy/SignedJar/keypass Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,1 @@ +password diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/time/test/java/time/TestInstant.java --- a/jdk/test/java/time/test/java/time/TestInstant.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/time/test/java/time/TestInstant.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,8 @@ import java.time.Instant; import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; +import static org.testng.Assert.assertEquals; /** * Test Instant. @@ -74,4 +76,24 @@ assertImmutable(Instant.class); } + @DataProvider(name="sampleEpochMillis") + private Object[][] provider_sampleEpochMillis() { + return new Object[][] { + {"Long.MAX_VALUE", Long.MAX_VALUE}, + {"Long.MAX_VALUE-1", Long.MAX_VALUE - 1}, + {"1", 1L}, + {"0", 0L}, + {"-1", -1L}, + {"Long.MIN_VALUE+1", Long.MIN_VALUE + 1}, + {"Long.MIN_VALUE", Long.MIN_VALUE} + }; + } + + @Test(dataProvider="sampleEpochMillis") + public void test_epochMillis(String name, long millis) { + Instant t1 = Instant.ofEpochMilli(millis); + long m = t1.toEpochMilli(); + assertEquals(millis, m, name); + } + } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/regex/PatternStreamTest.java --- a/jdk/test/java/util/regex/PatternStreamTest.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/util/regex/PatternStreamTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,8 @@ /** * @test - * @bug 8016846 8024341 - * @summary Unit tests for wrapping classes should delegate to default methods + * @bug 8016846 8024341 8071479 + * @summary Unit tests stream and lambda-based methods on Pattern and Matcher * @library ../stream/bootlib * @build java.util.stream.OpTestCase * @run testng/othervm PatternStreamTest @@ -34,158 +34,283 @@ import org.testng.annotations.Test; import java.util.ArrayList; +import java.util.Arrays; +import java.util.ConcurrentModificationException; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.LambdaTestHelpers; import java.util.stream.OpTestCase; import java.util.stream.Stream; import java.util.stream.TestData; +import static org.testng.Assert.*; + @Test public class PatternStreamTest extends OpTestCase { - @DataProvider(name = "Stream") + @DataProvider(name = "Patterns") public static Object[][] makeStreamTestData() { + // Each item must match the type signature of the consumer of this data + // String, String, Pattern List data = new ArrayList<>(); - String description = ""; - String input = "awgqwefg1fefw4vssv1vvv1"; - Pattern pattern = Pattern.compile("4"); - List expected = new ArrayList<>(); - expected.add("awgqwefg1fefw"); - expected.add("vssv1vvv1"); + String description = "All matches"; + String input = "XXXXXX"; + Pattern pattern = Pattern.compile("X"); + data.add(new Object[]{description, input, pattern}); + + description = "Bounded every other match"; + input = "XYXYXYYXYX"; + pattern = Pattern.compile("X"); + data.add(new Object[]{description, input, pattern}); - // Must match the type signature of the consumer of this data, testStrings - // String, String, Pattern, List - data.add(new Object[]{description, input, pattern, expected}); + description = "Every other match"; + input = "YXYXYXYYXYXY"; + pattern = Pattern.compile("X"); + data.add(new Object[]{description, input, pattern}); + + description = ""; + input = "awgqwefg1fefw4vssv1vvv1"; + pattern = Pattern.compile("4"); + data.add(new Object[]{description, input, pattern}); input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"; pattern = Pattern.compile("\u00a3a"); - expected = new ArrayList<>(); - expected.add("afbfq"); - expected.add("bgwgb"); - expected.add("wngnwggw"); - expected.add(""); - expected.add("hjrnhneerh"); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); input = "awgqwefg1fefw4vssv1vvv1"; pattern = Pattern.compile("1"); - expected = new ArrayList<>(); - expected.add("awgqwefg"); - expected.add("fefw4vssv"); - expected.add("vvv"); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"; pattern = Pattern.compile("1"); - expected = new ArrayList<>(); - expected.add("a\u4ebafg"); - expected.add("fefw\u4eba4\u9f9cvssv\u9f9c"); - expected.add("v\u672c\u672cvv"); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); input = "1\u56da23\u56da456\u56da7890"; pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - expected.add("1"); - expected.add("23"); - expected.add("456"); - expected.add("7890"); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"; pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - expected.add("1"); - expected.add("23\u9f9c\u672c\u672c"); - expected.add("456"); - expected.add("\u9f9c\u672c7890"); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); description = "Empty input"; input = ""; pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - expected.add(""); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); description = "Empty input with empty pattern"; input = ""; pattern = Pattern.compile(""); - expected = new ArrayList<>(); - expected.add(""); - - data.add(new Object[]{description, input, pattern, expected}); - + data.add(new Object[]{description, input, pattern}); description = "Multiple separators"; input = "This is,testing: with\tdifferent separators."; pattern = Pattern.compile("[ \t,:.]"); - expected = new ArrayList<>(); - expected.add("This"); - expected.add("is"); - expected.add("testing"); - expected.add(""); - expected.add("with"); - expected.add("different"); - expected.add("separators"); - + data.add(new Object[]{description, input, pattern}); description = "Repeated separators within and at end"; input = "boo:and:foo"; pattern = Pattern.compile("o"); - expected = new ArrayList<>(); - expected.add("b"); - expected.add(""); - expected.add(":and:f"); - + data.add(new Object[]{description, input, pattern}); description = "Many repeated separators within and at end"; input = "booooo:and:fooooo"; pattern = Pattern.compile("o"); - expected = new ArrayList<>(); - expected.add("b"); - expected.add(""); - expected.add(""); - expected.add(""); - expected.add(""); - expected.add(":and:f"); + data.add(new Object[]{description, input, pattern}); description = "Many repeated separators before last match"; input = "fooooo:"; pattern = Pattern.compile("o"); - expected = new ArrayList<>(); - expected.add("f"); - expected.add(""); - expected.add(""); - expected.add(""); - expected.add(""); - expected.add(":"); + data.add(new Object[] {description, input, pattern}); - data.add(new Object[] {description, input, pattern, expected}); return data.toArray(new Object[0][]); } - @Test(dataProvider = "Stream") - public void testStrings(String description, String input, Pattern pattern, List expected) { + @Test(dataProvider = "Patterns") + public void testPatternSplitAsStream(String description, String input, Pattern pattern) { + // Derive expected result from pattern.split + List expected = Arrays.asList(pattern.split(input)); + Supplier> ss = () -> pattern.splitAsStream(input); withData(TestData.Factory.ofSupplier(description, ss)) .stream(LambdaTestHelpers.identity()) .expectedResult(expected) .exercise(); } + + @Test(dataProvider = "Patterns") + public void testReplaceFirst(String description, String input, Pattern pattern) { + // Derive expected result from Matcher.replaceFirst(String ) + String expected = pattern.matcher(input).replaceFirst("R"); + String actual = pattern.matcher(input).replaceFirst(r -> "R"); + assertEquals(actual, expected); + } + + @Test(dataProvider = "Patterns") + public void testReplaceAll(String description, String input, Pattern pattern) { + // Derive expected result from Matcher.replaceAll(String ) + String expected = pattern.matcher(input).replaceAll("R"); + String actual = pattern.matcher(input).replaceAll(r -> "R"); + assertEquals(actual, expected); + + // Derive expected result from Matcher.find + Matcher m = pattern.matcher(input); + int expectedMatches = 0; + while (m.find()) { + expectedMatches++; + } + AtomicInteger actualMatches = new AtomicInteger(); + pattern.matcher(input).replaceAll(r -> "R" + actualMatches.incrementAndGet()); + assertEquals(expectedMatches, actualMatches.get()); + } + + @Test(dataProvider = "Patterns") + public void testMatchResults(String description, String input, Pattern pattern) { + // Derive expected result from Matcher.find + Matcher m = pattern.matcher(input); + List expected = new ArrayList<>(); + while (m.find()) { + expected.add(new MatchResultHolder(m)); + } + + Supplier> ss = () -> pattern.matcher(input).results(); + withData(TestData.Factory.ofSupplier(description, ss)) + .stream(s -> s.map(MatchResultHolder::new)) + .expectedResult(expected) + .exercise(); + } + + public void testFailfastMatchResults() { + Pattern p = Pattern.compile("X"); + Matcher m = p.matcher("XX"); + + Stream s = m.results(); + m.find(); + // Should start on the second match + assertEquals(s.count(), 1); + + // Fail fast without short-circuit + // Exercises Iterator.forEachRemaining + m.reset(); + try { + m.results().peek(mr -> m.reset()).count(); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + + m.reset(); + try { + m.results().peek(mr -> m.find()).count(); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + + // Fail fast with short-circuit + // Exercises Iterator.hasNext/next + m.reset(); + try { + m.results().peek(mr -> m.reset()).limit(2).count(); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + + m.reset(); + try { + m.results().peek(mr -> m.find()).limit(2).count(); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + } + + public void testFailfastReplace() { + Pattern p = Pattern.compile("X"); + Matcher m = p.matcher("XX"); + + // Fail fast without short-circuit + // Exercises Iterator.forEachRemaining + m.reset(); + try { + m.replaceFirst(mr -> { m.reset(); return "Y"; }); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + + m.reset(); + try { + m.replaceAll(mr -> { m.reset(); return "Y"; }); + fail(); + } catch (ConcurrentModificationException e) { + // Should reach here + } + } + + // A holder of MatchResult that can compare + static class MatchResultHolder implements Comparable { + final MatchResult mr; + + MatchResultHolder(Matcher m) { + this(m.toMatchResult()); + } + + MatchResultHolder(MatchResult mr) { + this.mr = mr; + } + + @Override + public int compareTo(MatchResultHolder that) { + int c = that.mr.group().compareTo(this.mr.group()); + if (c != 0) + return c; + + c = Integer.compare(that.mr.start(), this.mr.start()); + if (c != 0) + return c; + + c = Integer.compare(that.mr.end(), this.mr.end()); + if (c != 0) + return c; + + c = Integer.compare(that.mr.groupCount(), this.mr.groupCount()); + if (c != 0) + return c; + + for (int g = 0; g < this.mr.groupCount(); g++) { + c = that.mr.group(g).compareTo(this.mr.group(g)); + if (c != 0) + return c; + + c = Integer.compare(that.mr.start(g), this.mr.start(g)); + if (c != 0) + return c; + + c = Integer.compare(that.mr.end(g), this.mr.end(g)); + if (c != 0) + return c; + } + return 0; + } + + @Override + public boolean equals(Object that) { + if (this == that) return true; + if (that == null || getClass() != that.getClass()) return false; + + return this.compareTo((MatchResultHolder) that) == 0; + } + + @Override + public int hashCode() { + return mr.group().hashCode(); + } + } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/regex/RegExTest.java --- a/jdk/test/java/util/regex/RegExTest.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/util/regex/RegExTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -35,6 +35,7 @@ * 8027645 8035076 8039124 8035975 */ +import java.util.function.Function; import java.util.regex.*; import java.util.Random; import java.io.*; @@ -291,24 +292,26 @@ } private static void nullArgumentTest() { - check(new Runnable() { public void run() { Pattern.compile(null); }}); - check(new Runnable() { public void run() { Pattern.matches(null, null); }}); - check(new Runnable() { public void run() { Pattern.matches("xyz", null);}}); - check(new Runnable() { public void run() { Pattern.quote(null);}}); - check(new Runnable() { public void run() { Pattern.compile("xyz").split(null);}}); - check(new Runnable() { public void run() { Pattern.compile("xyz").matcher(null);}}); + check(() -> Pattern.compile(null)); + check(() -> Pattern.matches(null, null)); + check(() -> Pattern.matches("xyz", null)); + check(() -> Pattern.quote(null)); + check(() -> Pattern.compile("xyz").split(null)); + check(() -> Pattern.compile("xyz").matcher(null)); final Matcher m = Pattern.compile("xyz").matcher("xyz"); m.matches(); - check(new Runnable() { public void run() { m.appendTail((StringBuffer)null);}}); - check(new Runnable() { public void run() { m.appendTail((StringBuilder)null);}}); - check(new Runnable() { public void run() { m.replaceAll(null);}}); - check(new Runnable() { public void run() { m.replaceFirst(null);}}); - check(new Runnable() { public void run() { m.appendReplacement((StringBuffer)null, null);}}); - check(new Runnable() { public void run() { m.appendReplacement((StringBuilder)null, null);}}); - check(new Runnable() { public void run() { m.reset(null);}}); - check(new Runnable() { public void run() { Matcher.quoteReplacement(null);}}); - //check(new Runnable() { public void run() { m.usePattern(null);}}); + check(() -> m.appendTail((StringBuffer) null)); + check(() -> m.appendTail((StringBuilder)null)); + check(() -> m.replaceAll((String) null)); + check(() -> m.replaceAll((Function)null)); + check(() -> m.replaceFirst((String)null)); + check(() -> m.replaceFirst((Function) null)); + check(() -> m.appendReplacement((StringBuffer)null, null)); + check(() -> m.appendReplacement((StringBuilder)null, null)); + check(() -> m.reset(null)); + check(() -> Matcher.quoteReplacement(null)); + //check(() -> m.usePattern(null)); report("Null Argument"); } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorsTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,701 @@ +/* + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.tests.java.util.stream; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.StringJoiner; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.LambdaTestHelpers; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; +import java.util.stream.StreamOpFlagTestHelper; +import java.util.stream.StreamTestDataProvider; +import java.util.stream.TestData; + +import org.testng.annotations.Test; + +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.flatMapping; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.groupingByConcurrent; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.partitioningBy; +import static java.util.stream.Collectors.reducing; +import static java.util.stream.Collectors.toCollection; +import static java.util.stream.Collectors.toConcurrentMap; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.toSet; +import static java.util.stream.LambdaTestHelpers.assertContents; +import static java.util.stream.LambdaTestHelpers.assertContentsUnordered; +import static java.util.stream.LambdaTestHelpers.mDoubler; + +/* + * @test + * @bug 8071600 + * @summary Test for collectors. + */ +public class CollectorsTest extends OpTestCase { + + private static abstract class CollectorAssertion { + abstract void assertValue(U value, + Supplier> source, + boolean ordered) throws ReflectiveOperationException; + } + + static class MappingAssertion extends CollectorAssertion { + private final Function mapper; + private final CollectorAssertion downstream; + + MappingAssertion(Function mapper, CollectorAssertion downstream) { + this.mapper = mapper; + this.downstream = downstream; + } + + @Override + void assertValue(R value, Supplier> source, boolean ordered) throws ReflectiveOperationException { + downstream.assertValue(value, + () -> source.get().map(mapper::apply), + ordered); + } + } + + static class FlatMappingAssertion extends CollectorAssertion { + private final Function> mapper; + private final CollectorAssertion downstream; + + FlatMappingAssertion(Function> mapper, + CollectorAssertion downstream) { + this.mapper = mapper; + this.downstream = downstream; + } + + @Override + void assertValue(R value, Supplier> source, boolean ordered) throws ReflectiveOperationException { + downstream.assertValue(value, + () -> source.get().flatMap(mapper::apply), + ordered); + } + } + + static class GroupingByAssertion> extends CollectorAssertion { + private final Class clazz; + private final Function classifier; + private final CollectorAssertion downstream; + + GroupingByAssertion(Function classifier, Class clazz, + CollectorAssertion downstream) { + this.clazz = clazz; + this.classifier = classifier; + this.downstream = downstream; + } + + @Override + void assertValue(M map, + Supplier> source, + boolean ordered) throws ReflectiveOperationException { + if (!clazz.isAssignableFrom(map.getClass())) + fail(String.format("Class mismatch in GroupingByAssertion: %s, %s", clazz, map.getClass())); + assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet())); + for (Map.Entry entry : map.entrySet()) { + K key = entry.getKey(); + downstream.assertValue(entry.getValue(), + () -> source.get().filter(e -> classifier.apply(e).equals(key)), + ordered); + } + } + } + + static class ToMapAssertion> extends CollectorAssertion { + private final Class clazz; + private final Function keyFn; + private final Function valueFn; + private final BinaryOperator mergeFn; + + ToMapAssertion(Function keyFn, + Function valueFn, + BinaryOperator mergeFn, + Class clazz) { + this.clazz = clazz; + this.keyFn = keyFn; + this.valueFn = valueFn; + this.mergeFn = mergeFn; + } + + @Override + void assertValue(M map, Supplier> source, boolean ordered) throws ReflectiveOperationException { + if (!clazz.isAssignableFrom(map.getClass())) + fail(String.format("Class mismatch in ToMapAssertion: %s, %s", clazz, map.getClass())); + Set uniqueKeys = source.get().map(keyFn).collect(toSet()); + assertEquals(uniqueKeys, map.keySet()); + source.get().forEach(t -> { + K key = keyFn.apply(t); + V v = source.get() + .filter(e -> key.equals(keyFn.apply(e))) + .map(valueFn) + .reduce(mergeFn) + .get(); + assertEquals(map.get(key), v); + }); + } + } + + static class PartitioningByAssertion extends CollectorAssertion> { + private final Predicate predicate; + private final CollectorAssertion downstream; + + PartitioningByAssertion(Predicate predicate, CollectorAssertion downstream) { + this.predicate = predicate; + this.downstream = downstream; + } + + @Override + void assertValue(Map map, + Supplier> source, + boolean ordered) throws ReflectiveOperationException { + if (!Map.class.isAssignableFrom(map.getClass())) + fail(String.format("Class mismatch in PartitioningByAssertion: %s", map.getClass())); + assertEquals(2, map.size()); + downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered); + downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered); + } + } + + static class ToListAssertion extends CollectorAssertion> { + @Override + void assertValue(List value, Supplier> source, boolean ordered) + throws ReflectiveOperationException { + if (!List.class.isAssignableFrom(value.getClass())) + fail(String.format("Class mismatch in ToListAssertion: %s", value.getClass())); + Stream stream = source.get(); + List result = new ArrayList<>(); + for (Iterator it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add + result.add(it.next()); + if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered) + assertContents(value, result); + else + assertContentsUnordered(value, result); + } + } + + static class ToCollectionAssertion extends CollectorAssertion> { + private final Class clazz; + private final boolean targetOrdered; + + ToCollectionAssertion(Class clazz, boolean targetOrdered) { + this.clazz = clazz; + this.targetOrdered = targetOrdered; + } + + @Override + void assertValue(Collection value, Supplier> source, boolean ordered) + throws ReflectiveOperationException { + if (!clazz.isAssignableFrom(value.getClass())) + fail(String.format("Class mismatch in ToCollectionAssertion: %s, %s", clazz, value.getClass())); + Stream stream = source.get(); + Collection result = clazz.newInstance(); + for (Iterator it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add + result.add(it.next()); + if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered) + assertContents(value, result); + else + assertContentsUnordered(value, result); + } + } + + static class ReducingAssertion extends CollectorAssertion { + private final U identity; + private final Function mapper; + private final BinaryOperator reducer; + + ReducingAssertion(U identity, Function mapper, BinaryOperator reducer) { + this.identity = identity; + this.mapper = mapper; + this.reducer = reducer; + } + + @Override + void assertValue(U value, Supplier> source, boolean ordered) + throws ReflectiveOperationException { + Optional reduced = source.get().map(mapper).reduce(reducer); + if (value == null) + assertTrue(!reduced.isPresent()); + else if (!reduced.isPresent()) { + assertEquals(value, identity); + } + else { + assertEquals(value, reduced.get()); + } + } + } + + private ResultAsserter mapTabulationAsserter(boolean ordered) { + return (act, exp, ord, par) -> { + if (par && (!ordered || !ord)) { + CollectorsTest.nestedMapEqualityAssertion(act, exp); + } + else { + LambdaTestHelpers.assertContentsEqual(act, exp); + } + }; + } + + private + void exerciseMapCollection(TestData> data, + Collector collector, + CollectorAssertion assertion) + throws ReflectiveOperationException { + boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED); + + M m = withData(data) + .terminal(s -> s.collect(collector)) + .resultAsserter(mapTabulationAsserter(ordered)) + .exercise(); + assertion.assertValue(m, () -> data.stream(), ordered); + + m = withData(data) + .terminal(s -> s.unordered().collect(collector)) + .resultAsserter(mapTabulationAsserter(ordered)) + .exercise(); + assertion.assertValue(m, () -> data.stream(), false); + } + + private static void nestedMapEqualityAssertion(Object o1, Object o2) { + if (o1 instanceof Map) { + Map m1 = (Map) o1; + Map m2 = (Map) o2; + assertContentsUnordered(m1.keySet(), m2.keySet()); + for (Object k : m1.keySet()) + nestedMapEqualityAssertion(m1.get(k), m2.get(k)); + } + else if (o1 instanceof Collection) { + assertContentsUnordered(((Collection) o1), ((Collection) o2)); + } + else + assertEquals(o1, o2); + } + + private void assertCollect(TestData.OfRef data, + Collector collector, + Function, R> streamReduction) { + R check = streamReduction.apply(data.stream()); + withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise(); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testReducing(String name, TestData.OfRef data) throws ReflectiveOperationException { + assertCollect(data, Collectors.reducing(0, Integer::sum), + s -> s.reduce(0, Integer::sum)); + assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min), + s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE)); + assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max), + s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE)); + + assertCollect(data, Collectors.reducing(Integer::sum), + s -> s.reduce(Integer::sum)); + assertCollect(data, Collectors.minBy(Comparator.naturalOrder()), + s -> s.min(Integer::compare)); + assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()), + s -> s.max(Integer::compare)); + + assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum), + s -> s.map(x -> x*2).reduce(0, Integer::sum)); + + assertCollect(data, Collectors.summingLong(x -> x * 2L), + s -> s.map(x -> x*2L).reduce(0L, Long::sum)); + assertCollect(data, Collectors.summingInt(x -> x * 2), + s -> s.map(x -> x*2).reduce(0, Integer::sum)); + assertCollect(data, Collectors.summingDouble(x -> x * 2.0d), + s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum)); + + assertCollect(data, Collectors.averagingInt(x -> x * 2), + s -> s.mapToInt(x -> x * 2).average().orElse(0)); + assertCollect(data, Collectors.averagingLong(x -> x * 2), + s -> s.mapToLong(x -> x * 2).average().orElse(0)); + assertCollect(data, Collectors.averagingDouble(x -> x * 2), + s -> s.mapToDouble(x -> x * 2).average().orElse(0)); + + // Test explicit Collector.of + Collector avg2xint = Collector.of(() -> new long[2], + (a, b) -> { + a[0] += b * 2; + a[1]++; + }, + (a, b) -> { + a[0] += b[0]; + a[1] += b[1]; + return a; + }, + a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]); + assertCollect(data, avg2xint, + s -> s.mapToInt(x -> x * 2).average().orElse(0)); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testJoining(String name, TestData.OfRef data) throws ReflectiveOperationException { + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining())) + .expectedResult(join(data, "")) + .exercise(); + + Collector likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString); + withData(data) + .terminal(s -> s.map(Object::toString).collect(likeJoining)) + .expectedResult(join(data, "")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining(","))) + .expectedResult(join(data, ",")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]"))) + .expectedResult("[" + join(data, ",") + "]") + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString()) + .expectedResult(join(data, "")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(() -> new StringJoiner(","), + (sj, cs) -> sj.add(cs), + (j1, j2) -> j1.merge(j2)) + .toString()) + .expectedResult(join(data, ",")) + .exercise(); + + withData(data) + .terminal(s -> s.map(Object::toString) + .collect(() -> new StringJoiner(",", "[", "]"), + (sj, cs) -> sj.add(cs), + (j1, j2) -> j1.merge(j2)) + .toString()) + .expectedResult("[" + join(data, ",") + "]") + .exercise(); + } + + private String join(TestData.OfRef data, String delim) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (T i : data) { + if (!first) + sb.append(delim); + sb.append(i.toString()); + first = false; + } + return sb.toString(); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testSimpleToMap(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function keyFn = i -> i * 2; + Function valueFn = i -> i * 4; + + List dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new)); + Set dataAsSet = new HashSet<>(dataAsList); + + BinaryOperator sum = Integer::sum; + for (BinaryOperator op : Arrays.asList((u, v) -> u, + (u, v) -> v, + sum)) { + try { + exerciseMapCollection(data, toMap(keyFn, valueFn), + new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); + if (dataAsList.size() != dataAsSet.size()) + fail("Expected ISE on input with duplicates"); + } + catch (IllegalStateException e) { + if (dataAsList.size() == dataAsSet.size()) + fail("Expected no ISE on input without duplicates"); + } + + exerciseMapCollection(data, toMap(keyFn, valueFn, op), + new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); + + exerciseMapCollection(data, toMap(keyFn, valueFn, op, TreeMap::new), + new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class)); + } + + // For concurrent maps, only use commutative merge functions + try { + exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); + if (dataAsList.size() != dataAsSet.size()) + fail("Expected ISE on input with duplicates"); + } + catch (IllegalStateException e) { + if (dataAsList.size() == dataAsSet.size()) + fail("Expected no ISE on input without duplicates"); + } + + exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); + + exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new), + new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class)); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testSimpleGroupingBy(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function classifier = i -> i % 3; + + // Single-level groupBy + exerciseMapCollection(data, groupingBy(classifier), + new GroupingByAssertion<>(classifier, HashMap.class, + new ToListAssertion<>())); + exerciseMapCollection(data, groupingByConcurrent(classifier), + new GroupingByAssertion<>(classifier, ConcurrentHashMap.class, + new ToListAssertion<>())); + + // With explicit constructors + exerciseMapCollection(data, + groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)), + new GroupingByAssertion<>(classifier, TreeMap.class, + new ToCollectionAssertion(HashSet.class, false))); + exerciseMapCollection(data, + groupingByConcurrent(classifier, ConcurrentSkipListMap::new, + toCollection(HashSet::new)), + new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class, + new ToCollectionAssertion(HashSet.class, false))); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testGroupingByWithMapping(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function classifier = i -> i % 3; + Function mapper = i -> i * 2; + + exerciseMapCollection(data, + groupingBy(classifier, mapping(mapper, toList())), + new GroupingByAssertion<>(classifier, HashMap.class, + new MappingAssertion<>(mapper, + new ToListAssertion<>()))); + } + + @Test + public void testFlatMappingClose() { + Function classifier = i -> i; + AtomicInteger ai = new AtomicInteger(); + Function> flatMapper = i -> Stream.of(i, i).onClose(ai::getAndIncrement); + Map> m = Stream.of(1, 2).collect(groupingBy(classifier, flatMapping(flatMapper, toList()))); + assertEquals(m.size(), ai.get()); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testGroupingByWithFlatMapping(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function classifier = i -> i % 3; + Function> flatMapperByNull = i -> null; + Function> flatMapperBy0 = i -> Stream.empty(); + Function> flatMapperBy2 = i -> Stream.of(i, i); + + exerciseMapCollection(data, + groupingBy(classifier, flatMapping(flatMapperByNull, toList())), + new GroupingByAssertion<>(classifier, HashMap.class, + new FlatMappingAssertion<>(flatMapperBy0, + new ToListAssertion<>()))); + exerciseMapCollection(data, + groupingBy(classifier, flatMapping(flatMapperBy0, toList())), + new GroupingByAssertion<>(classifier, HashMap.class, + new FlatMappingAssertion<>(flatMapperBy0, + new ToListAssertion<>()))); + exerciseMapCollection(data, + groupingBy(classifier, flatMapping(flatMapperBy2, toList())), + new GroupingByAssertion<>(classifier, HashMap.class, + new FlatMappingAssertion<>(flatMapperBy2, + new ToListAssertion<>()))); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testTwoLevelGroupingBy(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function classifier = i -> i % 6; + Function classifier2 = i -> i % 23; + + // Two-level groupBy + exerciseMapCollection(data, + groupingBy(classifier, groupingBy(classifier2)), + new GroupingByAssertion<>(classifier, HashMap.class, + new GroupingByAssertion<>(classifier2, HashMap.class, + new ToListAssertion<>()))); + // with concurrent as upstream + exerciseMapCollection(data, + groupingByConcurrent(classifier, groupingBy(classifier2)), + new GroupingByAssertion<>(classifier, ConcurrentHashMap.class, + new GroupingByAssertion<>(classifier2, HashMap.class, + new ToListAssertion<>()))); + // with concurrent as downstream + exerciseMapCollection(data, + groupingBy(classifier, groupingByConcurrent(classifier2)), + new GroupingByAssertion<>(classifier, HashMap.class, + new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class, + new ToListAssertion<>()))); + // with concurrent as upstream and downstream + exerciseMapCollection(data, + groupingByConcurrent(classifier, groupingByConcurrent(classifier2)), + new GroupingByAssertion<>(classifier, ConcurrentHashMap.class, + new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class, + new ToListAssertion<>()))); + + // With explicit constructors + exerciseMapCollection(data, + groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))), + new GroupingByAssertion<>(classifier, TreeMap.class, + new GroupingByAssertion<>(classifier2, TreeMap.class, + new ToCollectionAssertion(HashSet.class, false)))); + // with concurrent as upstream + exerciseMapCollection(data, + groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())), + new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class, + new GroupingByAssertion<>(classifier2, TreeMap.class, + new ToListAssertion<>()))); + // with concurrent as downstream + exerciseMapCollection(data, + groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())), + new GroupingByAssertion<>(classifier, TreeMap.class, + new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class, + new ToListAssertion<>()))); + // with concurrent as upstream and downstream + exerciseMapCollection(data, + groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())), + new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class, + new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class, + new ToListAssertion<>()))); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testGroupubgByWithReducing(String name, TestData.OfRef data) throws ReflectiveOperationException { + Function classifier = i -> i % 3; + + // Single-level simple reduce + exerciseMapCollection(data, + groupingBy(classifier, reducing(0, Integer::sum)), + new GroupingByAssertion<>(classifier, HashMap.class, + new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); + // with concurrent + exerciseMapCollection(data, + groupingByConcurrent(classifier, reducing(0, Integer::sum)), + new GroupingByAssertion<>(classifier, ConcurrentHashMap.class, + new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); + + // With explicit constructors + exerciseMapCollection(data, + groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)), + new GroupingByAssertion<>(classifier, TreeMap.class, + new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); + // with concurrent + exerciseMapCollection(data, + groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)), + new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class, + new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); + + // Single-level map-reduce + exerciseMapCollection(data, + groupingBy(classifier, reducing(0, mDoubler, Integer::sum)), + new GroupingByAssertion<>(classifier, HashMap.class, + new ReducingAssertion<>(0, mDoubler, Integer::sum))); + // with concurrent + exerciseMapCollection(data, + groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)), + new GroupingByAssertion<>(classifier, ConcurrentHashMap.class, + new ReducingAssertion<>(0, mDoubler, Integer::sum))); + + // With explicit constructors + exerciseMapCollection(data, + groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)), + new GroupingByAssertion<>(classifier, TreeMap.class, + new ReducingAssertion<>(0, mDoubler, Integer::sum))); + // with concurrent + exerciseMapCollection(data, + groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)), + new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class, + new ReducingAssertion<>(0, mDoubler, Integer::sum))); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testSimplePartitioningBy(String name, TestData.OfRef data) throws ReflectiveOperationException { + Predicate classifier = i -> i % 3 == 0; + + // Single-level partition to downstream List + exerciseMapCollection(data, + partitioningBy(classifier), + new PartitioningByAssertion<>(classifier, new ToListAssertion<>())); + exerciseMapCollection(data, + partitioningBy(classifier, toList()), + new PartitioningByAssertion<>(classifier, new ToListAssertion<>())); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testTwoLevelPartitioningBy(String name, TestData.OfRef data) throws ReflectiveOperationException { + Predicate classifier = i -> i % 3 == 0; + Predicate classifier2 = i -> i % 7 == 0; + + // Two level partition + exerciseMapCollection(data, + partitioningBy(classifier, partitioningBy(classifier2)), + new PartitioningByAssertion<>(classifier, + new PartitioningByAssertion(classifier2, new ToListAssertion<>()))); + + // Two level partition with reduce + exerciseMapCollection(data, + partitioningBy(classifier, reducing(0, Integer::sum)), + new PartitioningByAssertion<>(classifier, + new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); + } + + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + public void testComposeFinisher(String name, TestData.OfRef data) throws ReflectiveOperationException { + List asList = exerciseTerminalOps(data, s -> s.collect(toList())); + List asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList))); + assertEquals(asList, asImmutableList); + try { + asImmutableList.add(0); + fail("Expecting immutable result"); + } + catch (UnsupportedOperationException ignored) { } + } + +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,19 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import java.util.stream.*; +import java.util.function.Supplier; +import java.util.stream.DoubleStream; +import java.util.stream.DoubleStreamTestDataProvider; +import java.util.stream.IntStream; +import java.util.stream.IntStreamTestDataProvider; +import java.util.stream.LongStream; +import java.util.stream.LongStreamTestDataProvider; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; +import java.util.stream.StreamTestDataProvider; +import java.util.stream.TestData; import static java.util.stream.LambdaTestHelpers.*; import static java.util.stream.ThowableHelper.checkNPE; @@ -66,6 +77,59 @@ exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars)); } + @Test + public void testClose() { + AtomicInteger before = new AtomicInteger(); + AtomicInteger onClose = new AtomicInteger(); + + Supplier> s = () -> { + before.set(0); onClose.set(0); + return Stream.of(1, 2).peek(e -> before.getAndIncrement()); + }; + + s.get().flatMap(i -> Stream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + + s.get().flatMapToInt(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + + s.get().flatMapToLong(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + + s.get().flatMapToDouble(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + } + + @Test + public void testIntClose() { + AtomicInteger before = new AtomicInteger(); + AtomicInteger onClose = new AtomicInteger(); + + IntStream.of(1, 2).peek(e -> before.getAndIncrement()). + flatMap(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + } + + @Test + public void testLongClose() { + AtomicInteger before = new AtomicInteger(); + AtomicInteger onClose = new AtomicInteger(); + + LongStream.of(1, 2).peek(e -> before.getAndIncrement()). + flatMap(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + } + + @Test + public void testDoubleClose() { + AtomicInteger before = new AtomicInteger(); + AtomicInteger onClose = new AtomicInteger(); + + DoubleStream.of(1, 2).peek(e -> before.getAndIncrement()). + flatMap(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count(); + assertEquals(before.get(), onClose.get()); + } + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) public void testOps(String name, TestData.OfRef data) { Collection result = exerciseOps(data, s -> s.flatMap(mfId)); diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java Thu Mar 05 11:26:17 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,621 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.openjdk.tests.java.util.stream; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.StringJoiner; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.function.BinaryOperator; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.LambdaTestHelpers; -import java.util.stream.OpTestCase; -import java.util.stream.Stream; -import java.util.stream.StreamOpFlagTestHelper; -import java.util.stream.StreamTestDataProvider; -import java.util.stream.TestData; - -import org.testng.annotations.Test; - -import static java.util.stream.Collectors.collectingAndThen; -import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.groupingByConcurrent; -import static java.util.stream.Collectors.partitioningBy; -import static java.util.stream.Collectors.reducing; -import static java.util.stream.Collectors.toCollection; -import static java.util.stream.Collectors.toConcurrentMap; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; -import static java.util.stream.Collectors.toSet; -import static java.util.stream.LambdaTestHelpers.assertContents; -import static java.util.stream.LambdaTestHelpers.assertContentsUnordered; -import static java.util.stream.LambdaTestHelpers.mDoubler; - -/** - * TabulatorsTest - * - * @author Brian Goetz - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class TabulatorsTest extends OpTestCase { - - private static abstract class TabulationAssertion { - abstract void assertValue(U value, - Supplier> source, - boolean ordered) throws ReflectiveOperationException; - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - static class GroupedMapAssertion> extends TabulationAssertion { - private final Class clazz; - private final Function classifier; - private final TabulationAssertion downstream; - - protected GroupedMapAssertion(Function classifier, - Class clazz, - TabulationAssertion downstream) { - this.clazz = clazz; - this.classifier = classifier; - this.downstream = downstream; - } - - void assertValue(M map, - Supplier> source, - boolean ordered) throws ReflectiveOperationException { - if (!clazz.isAssignableFrom(map.getClass())) - fail(String.format("Class mismatch in GroupedMapAssertion: %s, %s", clazz, map.getClass())); - assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet())); - for (Map.Entry entry : map.entrySet()) { - K key = entry.getKey(); - downstream.assertValue(entry.getValue(), - () -> source.get().filter(e -> classifier.apply(e).equals(key)), - ordered); - } - } - } - - static class ToMapAssertion> extends TabulationAssertion { - private final Class clazz; - private final Function keyFn; - private final Function valueFn; - private final BinaryOperator mergeFn; - - ToMapAssertion(Function keyFn, - Function valueFn, - BinaryOperator mergeFn, - Class clazz) { - this.clazz = clazz; - this.keyFn = keyFn; - this.valueFn = valueFn; - this.mergeFn = mergeFn; - } - - @Override - void assertValue(M map, Supplier> source, boolean ordered) throws ReflectiveOperationException { - Set uniqueKeys = source.get().map(keyFn).collect(toSet()); - assertTrue(clazz.isAssignableFrom(map.getClass())); - assertEquals(uniqueKeys, map.keySet()); - source.get().forEach(t -> { - K key = keyFn.apply(t); - V v = source.get() - .filter(e -> key.equals(keyFn.apply(e))) - .map(valueFn) - .reduce(mergeFn) - .get(); - assertEquals(map.get(key), v); - }); - } - } - - static class PartitionAssertion extends TabulationAssertion> { - private final Predicate predicate; - private final TabulationAssertion downstream; - - protected PartitionAssertion(Predicate predicate, - TabulationAssertion downstream) { - this.predicate = predicate; - this.downstream = downstream; - } - - void assertValue(Map map, - Supplier> source, - boolean ordered) throws ReflectiveOperationException { - if (!Map.class.isAssignableFrom(map.getClass())) - fail(String.format("Class mismatch in PartitionAssertion: %s", map.getClass())); - assertEquals(2, map.size()); - downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered); - downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered); - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - static class ListAssertion extends TabulationAssertion> { - @Override - void assertValue(List value, Supplier> source, boolean ordered) - throws ReflectiveOperationException { - if (!List.class.isAssignableFrom(value.getClass())) - fail(String.format("Class mismatch in ListAssertion: %s", value.getClass())); - Stream stream = source.get(); - List result = new ArrayList<>(); - for (Iterator it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add - result.add(it.next()); - if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered) - assertContents(value, result); - else - assertContentsUnordered(value, result); - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - static class CollectionAssertion extends TabulationAssertion> { - private final Class clazz; - private final boolean targetOrdered; - - protected CollectionAssertion(Class clazz, boolean targetOrdered) { - this.clazz = clazz; - this.targetOrdered = targetOrdered; - } - - @Override - void assertValue(Collection value, Supplier> source, boolean ordered) - throws ReflectiveOperationException { - if (!clazz.isAssignableFrom(value.getClass())) - fail(String.format("Class mismatch in CollectionAssertion: %s, %s", clazz, value.getClass())); - Stream stream = source.get(); - Collection result = clazz.newInstance(); - for (Iterator it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add - result.add(it.next()); - if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered) - assertContents(value, result); - else - assertContentsUnordered(value, result); - } - } - - static class ReduceAssertion extends TabulationAssertion { - private final U identity; - private final Function mapper; - private final BinaryOperator reducer; - - ReduceAssertion(U identity, Function mapper, BinaryOperator reducer) { - this.identity = identity; - this.mapper = mapper; - this.reducer = reducer; - } - - @Override - void assertValue(U value, Supplier> source, boolean ordered) - throws ReflectiveOperationException { - Optional reduced = source.get().map(mapper).reduce(reducer); - if (value == null) - assertTrue(!reduced.isPresent()); - else if (!reduced.isPresent()) { - assertEquals(value, identity); - } - else { - assertEquals(value, reduced.get()); - } - } - } - - private ResultAsserter mapTabulationAsserter(boolean ordered) { - return (act, exp, ord, par) -> { - if (par && (!ordered || !ord)) { - TabulatorsTest.nestedMapEqualityAssertion(act, exp); - } - else { - LambdaTestHelpers.assertContentsEqual(act, exp); - } - }; - } - - private - void exerciseMapTabulation(TestData> data, - Collector collector, - TabulationAssertion assertion) - throws ReflectiveOperationException { - boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED); - - M m = withData(data) - .terminal(s -> s.collect(collector)) - .resultAsserter(mapTabulationAsserter(ordered)) - .exercise(); - assertion.assertValue(m, () -> data.stream(), ordered); - - m = withData(data) - .terminal(s -> s.unordered().collect(collector)) - .resultAsserter(mapTabulationAsserter(ordered)) - .exercise(); - assertion.assertValue(m, () -> data.stream(), false); - } - - private static void nestedMapEqualityAssertion(Object o1, Object o2) { - if (o1 instanceof Map) { - Map m1 = (Map) o1; - Map m2 = (Map) o2; - assertContentsUnordered(m1.keySet(), m2.keySet()); - for (Object k : m1.keySet()) - nestedMapEqualityAssertion(m1.get(k), m2.get(k)); - } - else if (o1 instanceof Collection) { - assertContentsUnordered(((Collection) o1), ((Collection) o2)); - } - else - assertEquals(o1, o2); - } - - private void assertCollect(TestData.OfRef data, - Collector collector, - Function, R> streamReduction) { - R check = streamReduction.apply(data.stream()); - withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise(); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testReduce(String name, TestData.OfRef data) throws ReflectiveOperationException { - assertCollect(data, Collectors.reducing(0, Integer::sum), - s -> s.reduce(0, Integer::sum)); - assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min), - s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE)); - assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max), - s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE)); - - assertCollect(data, Collectors.reducing(Integer::sum), - s -> s.reduce(Integer::sum)); - assertCollect(data, Collectors.minBy(Comparator.naturalOrder()), - s -> s.min(Integer::compare)); - assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()), - s -> s.max(Integer::compare)); - - assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum), - s -> s.map(x -> x*2).reduce(0, Integer::sum)); - - assertCollect(data, Collectors.summingLong(x -> x * 2L), - s -> s.map(x -> x*2L).reduce(0L, Long::sum)); - assertCollect(data, Collectors.summingInt(x -> x * 2), - s -> s.map(x -> x*2).reduce(0, Integer::sum)); - assertCollect(data, Collectors.summingDouble(x -> x * 2.0d), - s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum)); - - assertCollect(data, Collectors.averagingInt(x -> x * 2), - s -> s.mapToInt(x -> x * 2).average().orElse(0)); - assertCollect(data, Collectors.averagingLong(x -> x * 2), - s -> s.mapToLong(x -> x * 2).average().orElse(0)); - assertCollect(data, Collectors.averagingDouble(x -> x * 2), - s -> s.mapToDouble(x -> x * 2).average().orElse(0)); - - // Test explicit Collector.of - Collector avg2xint = Collector.of(() -> new long[2], - (a, b) -> { - a[0] += b * 2; - a[1]++; - }, - (a, b) -> { - a[0] += b[0]; - a[1] += b[1]; - return a; - }, - a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]); - assertCollect(data, avg2xint, - s -> s.mapToInt(x -> x * 2).average().orElse(0)); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testJoin(String name, TestData.OfRef data) throws ReflectiveOperationException { - withData(data) - .terminal(s -> s.map(Object::toString).collect(Collectors.joining())) - .expectedResult(join(data, "")) - .exercise(); - - Collector likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString); - withData(data) - .terminal(s -> s.map(Object::toString).collect(likeJoining)) - .expectedResult(join(data, "")) - .exercise(); - - withData(data) - .terminal(s -> s.map(Object::toString).collect(Collectors.joining(","))) - .expectedResult(join(data, ",")) - .exercise(); - - withData(data) - .terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]"))) - .expectedResult("[" + join(data, ",") + "]") - .exercise(); - - withData(data) - .terminal(s -> s.map(Object::toString) - .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) - .toString()) - .expectedResult(join(data, "")) - .exercise(); - - withData(data) - .terminal(s -> s.map(Object::toString) - .collect(() -> new StringJoiner(","), - (sj, cs) -> sj.add(cs), - (j1, j2) -> j1.merge(j2)) - .toString()) - .expectedResult(join(data, ",")) - .exercise(); - - withData(data) - .terminal(s -> s.map(Object::toString) - .collect(() -> new StringJoiner(",", "[", "]"), - (sj, cs) -> sj.add(cs), - (j1, j2) -> j1.merge(j2)) - .toString()) - .expectedResult("[" + join(data, ",") + "]") - .exercise(); - } - - private String join(TestData.OfRef data, String delim) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (T i : data) { - if (!first) - sb.append(delim); - sb.append(i.toString()); - first = false; - } - return sb.toString(); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testSimpleToMap(String name, TestData.OfRef data) throws ReflectiveOperationException { - Function keyFn = i -> i * 2; - Function valueFn = i -> i * 4; - - List dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new)); - Set dataAsSet = new HashSet<>(dataAsList); - - BinaryOperator sum = Integer::sum; - for (BinaryOperator op : Arrays.asList((u, v) -> u, - (u, v) -> v, - sum)) { - try { - exerciseMapTabulation(data, toMap(keyFn, valueFn), - new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); - if (dataAsList.size() != dataAsSet.size()) - fail("Expected ISE on input with duplicates"); - } - catch (IllegalStateException e) { - if (dataAsList.size() == dataAsSet.size()) - fail("Expected no ISE on input without duplicates"); - } - - exerciseMapTabulation(data, toMap(keyFn, valueFn, op), - new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class)); - - exerciseMapTabulation(data, toMap(keyFn, valueFn, op, TreeMap::new), - new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class)); - } - - // For concurrent maps, only use commutative merge functions - try { - exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn), - new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); - if (dataAsList.size() != dataAsSet.size()) - fail("Expected ISE on input with duplicates"); - } - catch (IllegalStateException e) { - if (dataAsList.size() == dataAsSet.size()) - fail("Expected no ISE on input without duplicates"); - } - - exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum), - new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class)); - - exerciseMapTabulation(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new), - new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class)); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testSimpleGroupBy(String name, TestData.OfRef data) throws ReflectiveOperationException { - Function classifier = i -> i % 3; - - // Single-level groupBy - exerciseMapTabulation(data, groupingBy(classifier), - new GroupedMapAssertion<>(classifier, HashMap.class, - new ListAssertion<>())); - exerciseMapTabulation(data, groupingByConcurrent(classifier), - new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class, - new ListAssertion<>())); - - // With explicit constructors - exerciseMapTabulation(data, - groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)), - new GroupedMapAssertion<>(classifier, TreeMap.class, - new CollectionAssertion(HashSet.class, false))); - exerciseMapTabulation(data, - groupingByConcurrent(classifier, ConcurrentSkipListMap::new, - toCollection(HashSet::new)), - new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class, - new CollectionAssertion(HashSet.class, false))); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testTwoLevelGroupBy(String name, TestData.OfRef data) throws ReflectiveOperationException { - Function classifier = i -> i % 6; - Function classifier2 = i -> i % 23; - - // Two-level groupBy - exerciseMapTabulation(data, - groupingBy(classifier, groupingBy(classifier2)), - new GroupedMapAssertion<>(classifier, HashMap.class, - new GroupedMapAssertion<>(classifier2, HashMap.class, - new ListAssertion<>()))); - // with concurrent as upstream - exerciseMapTabulation(data, - groupingByConcurrent(classifier, groupingBy(classifier2)), - new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class, - new GroupedMapAssertion<>(classifier2, HashMap.class, - new ListAssertion<>()))); - // with concurrent as downstream - exerciseMapTabulation(data, - groupingBy(classifier, groupingByConcurrent(classifier2)), - new GroupedMapAssertion<>(classifier, HashMap.class, - new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class, - new ListAssertion<>()))); - // with concurrent as upstream and downstream - exerciseMapTabulation(data, - groupingByConcurrent(classifier, groupingByConcurrent(classifier2)), - new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class, - new GroupedMapAssertion<>(classifier2, ConcurrentHashMap.class, - new ListAssertion<>()))); - - // With explicit constructors - exerciseMapTabulation(data, - groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))), - new GroupedMapAssertion<>(classifier, TreeMap.class, - new GroupedMapAssertion<>(classifier2, TreeMap.class, - new CollectionAssertion(HashSet.class, false)))); - // with concurrent as upstream - exerciseMapTabulation(data, - groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())), - new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class, - new GroupedMapAssertion<>(classifier2, TreeMap.class, - new ListAssertion<>()))); - // with concurrent as downstream - exerciseMapTabulation(data, - groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())), - new GroupedMapAssertion<>(classifier, TreeMap.class, - new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class, - new ListAssertion<>()))); - // with concurrent as upstream and downstream - exerciseMapTabulation(data, - groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())), - new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class, - new GroupedMapAssertion<>(classifier2, ConcurrentSkipListMap.class, - new ListAssertion<>()))); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testGroupedReduce(String name, TestData.OfRef data) throws ReflectiveOperationException { - Function classifier = i -> i % 3; - - // Single-level simple reduce - exerciseMapTabulation(data, - groupingBy(classifier, reducing(0, Integer::sum)), - new GroupedMapAssertion<>(classifier, HashMap.class, - new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); - // with concurrent - exerciseMapTabulation(data, - groupingByConcurrent(classifier, reducing(0, Integer::sum)), - new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class, - new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); - - // With explicit constructors - exerciseMapTabulation(data, - groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)), - new GroupedMapAssertion<>(classifier, TreeMap.class, - new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); - // with concurrent - exerciseMapTabulation(data, - groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)), - new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class, - new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); - - // Single-level map-reduce - exerciseMapTabulation(data, - groupingBy(classifier, reducing(0, mDoubler, Integer::sum)), - new GroupedMapAssertion<>(classifier, HashMap.class, - new ReduceAssertion<>(0, mDoubler, Integer::sum))); - // with concurrent - exerciseMapTabulation(data, - groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)), - new GroupedMapAssertion<>(classifier, ConcurrentHashMap.class, - new ReduceAssertion<>(0, mDoubler, Integer::sum))); - - // With explicit constructors - exerciseMapTabulation(data, - groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)), - new GroupedMapAssertion<>(classifier, TreeMap.class, - new ReduceAssertion<>(0, mDoubler, Integer::sum))); - // with concurrent - exerciseMapTabulation(data, - groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)), - new GroupedMapAssertion<>(classifier, ConcurrentSkipListMap.class, - new ReduceAssertion<>(0, mDoubler, Integer::sum))); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testSimplePartition(String name, TestData.OfRef data) throws ReflectiveOperationException { - Predicate classifier = i -> i % 3 == 0; - - // Single-level partition to downstream List - exerciseMapTabulation(data, - partitioningBy(classifier), - new PartitionAssertion<>(classifier, new ListAssertion<>())); - exerciseMapTabulation(data, - partitioningBy(classifier, toList()), - new PartitionAssertion<>(classifier, new ListAssertion<>())); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testTwoLevelPartition(String name, TestData.OfRef data) throws ReflectiveOperationException { - Predicate classifier = i -> i % 3 == 0; - Predicate classifier2 = i -> i % 7 == 0; - - // Two level partition - exerciseMapTabulation(data, - partitioningBy(classifier, partitioningBy(classifier2)), - new PartitionAssertion<>(classifier, - new PartitionAssertion(classifier2, new ListAssertion<>()))); - - // Two level partition with reduce - exerciseMapTabulation(data, - partitioningBy(classifier, reducing(0, Integer::sum)), - new PartitionAssertion<>(classifier, - new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum))); - } - - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) - public void testComposeFinisher(String name, TestData.OfRef data) throws ReflectiveOperationException { - List asList = exerciseTerminalOps(data, s -> s.collect(toList())); - List asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList))); - assertEquals(asList, asImmutableList); - try { - asImmutableList.add(0); - fail("Expecting immutable result"); - } - catch (UnsupportedOperationException ignored) { } - } - -} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/java/util/zip/TestExtraTime.java --- a/jdk/test/java/util/zip/TestExtraTime.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/java/util/zip/TestExtraTime.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,7 @@ } testNullHandling(); + testTimeConversions(); } static void test(FileTime mtime, FileTime atime, FileTime ctime, @@ -178,4 +179,33 @@ // pass } } + + // verify that setting and getting any time is possible as per the intent + // of 4759491 + static void testTimeConversions() { + // Sample across the entire range + long step = Long.MAX_VALUE / 100L; + testTimeConversions(Long.MIN_VALUE, Long.MAX_VALUE - step, step); + + // Samples through the near future + long currentTime = System.currentTimeMillis(); + testTimeConversions(currentTime, currentTime + 1_000_000, 10_000); + } + + static void testTimeConversions(long from, long to, long step) { + ZipEntry ze = new ZipEntry("TestExtraTime.java"); + for (long time = from; time <= to; time += step) { + ze.setTime(time); + FileTime lastModifiedTime = ze.getLastModifiedTime(); + if (lastModifiedTime.toMillis() != time) { + throw new RuntimeException("setTime should make getLastModifiedTime " + + "return the specified instant: " + time + + " got: " + lastModifiedTime.toMillis()); + } + if (ze.getTime() != time) { + throw new RuntimeException("getTime after setTime, expected: " + + time + " got: " + ze.getTime()); + } + } + } } diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/javax/accessibility/8069268/bug8069268.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/accessibility/8069268/bug8069268.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8069268 + @summary Tests that only one ContainerListener exists for AccessibleJComponent of JRootPane + @author Vivi An +*/ +import javax.swing.*; +import java.awt.event.*; +import javax.accessibility.*; + +public class bug8069268{ + public static void main(String[] args) throws Exception { + TestableRootPane rootPane = new TestableRootPane(); + + // Get accesibleContext and then AccessibleJComponent, call the function + // addPropertyChangeListener to trigger container listener to be added + AccessibleContext acc = rootPane.getAccessibleContext(); + JComponent.AccessibleJComponent accJ = (JComponent.AccessibleJComponent) acc; + accJ.addPropertyChangeListener(null); + + // Test how many container listener(s) exist(s), should only have 1 + if (!rootPane.testContainerListener()) + throw new RuntimeException("Failed test for bug 8069268"); + } + + private static class TestableRootPane extends JRootPane { + public boolean testContainerListener() { + boolean result = false; + ContainerListener[] listeners = getContainerListeners(); + System.out.println("ContainerListener number is " + listeners.length); + result = (listeners.length == 1) ? true : false; + return result; + } + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/javax/sound/midi/Devices/InitializationHang.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/sound/midi/Devices/InitializationHang.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Toolkit; + +import javax.sound.midi.MidiSystem; + +/** + * @test + * @bug 8068412 + * @author Sergey Bylokhov + */ +public final class InitializationHang { + + public static void main(final String[] argv) throws Exception { + MidiSystem.getReceiver(); + Toolkit.getDefaultToolkit(); + } +} + diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/javax/swing/JMenu/8071705/bug8071705.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JMenu/8071705/bug8071705.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8071705 + * @summary Java application menu misbehaves when running multiple screen stacked vertically + * @build bug8071705 + * @run main/othervm bug8071705 + */ + +import java.awt.Dimension; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class bug8071705 { + + public static void main(String[] args) throws Exception { + + final CountDownLatch latch = new CountDownLatch(1); + final boolean [] result = new boolean[1]; + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JFrame frame = createGUI(); + GraphicsDevice[] devices = checkScreens(); + + // check if we have more than one and if they are stacked + // vertically + GraphicsDevice device = checkConfigs(devices); + if (device == null) { + // just pass the test + frame.dispose(); + result[0] = true; + latch.countDown(); + } else { + FrameListener listener = + new FrameListener(device, latch, result); + frame.addComponentListener(listener); + frame.setVisible(true); + } + } + }); + + latch.await(); + + if (result[0] == false) { + throw new RuntimeException("popup menu rendered in wrong position"); + } + + System.out.println("OK"); + } + + private static GraphicsDevice[] checkScreens() { + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + return ge.getScreenDevices(); + } + + private static JFrame createGUI() { + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Some menu"); + menuBar.add(menu); + + for (int i = 0; i < 10; i++) { + menu.add(new JMenuItem("Some menu #" + i)); + } + + JFrame frame = new JFrame(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setMinimumSize(new Dimension(200, 200)); + frame.setJMenuBar(menuBar); + return frame; + } + + private static GraphicsDevice checkConfigs(GraphicsDevice[] devices) { + + GraphicsDevice correctDevice = null; + if (devices.length < 2) { + return correctDevice; + } + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Rectangle screenBounds = new Rectangle(toolkit.getScreenSize()); + int halfScreen = screenBounds.height/2; + + for(int i = 0; i < devices.length; i++) { + if(devices[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) { + GraphicsConfiguration conf = + devices[i].getDefaultConfiguration(); + Rectangle bounds = conf.getBounds(); + if (bounds.y >= halfScreen) { + // found + correctDevice = devices[i]; + break; + } + } + } + return correctDevice; + } + + private static class FrameListener extends ComponentAdapter { + + private GraphicsDevice device; + private CountDownLatch latch; + private boolean [] result; + public FrameListener(GraphicsDevice device, + CountDownLatch latch, + boolean [] result) + { + this.device = device; + this.latch = latch; + this.result = result; + } + + @Override + public void componentShown(ComponentEvent e) { + JFrame frame = (JFrame) e.getComponent(); + + runActualTest(device, latch, frame, result); + + frame.setVisible(false); + frame.dispose(); + latch.countDown(); + } + } + + private static Rectangle setLocation(JFrame frame, GraphicsDevice device) { + GraphicsConfiguration conf = device.getDefaultConfiguration(); + Rectangle bounds = conf.getBounds(); + + // put just below half screen + int x = bounds.x + bounds.width/2; + int y = bounds.y + bounds.height/2; + frame.setLocation(x, y); + + return bounds; + } + + private static void runActualTest(GraphicsDevice device, + CountDownLatch latch, + JFrame frame, + boolean [] result) + { + Rectangle screenBounds = setLocation(frame, device); + JMenu menu = frame.getJMenuBar().getMenu(0); + menu.doClick(); + + Point location = menu.getLocationOnScreen(); + JPopupMenu pm = menu.getPopupMenu(); + Dimension pmSize = pm.getSize(); + + int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY"); + int height = location.y + yOffset + pmSize.height + menu.getHeight(); + int available = screenBounds.y + screenBounds.height - height; + if (available > 0) { + Point origin = pm.getLocationOnScreen(); + if (origin.y < location.y) { + // growing upward, wrong! + result[0] = false; + } else { + // growing downward, ok! + result[0] = true; + } + } else { + // there is no space, growing upward would be ok, so we pass + result[0] = true; + } + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/javax/swing/JTree/8072676/TreeClipTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JTree/8072676/TreeClipTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; + +/* + * @test + * @bug 8072676 + * @summary Checks if the tree painter doesn't expand existing clip + * @author Anton Nashatyrev + */ +public class TreeClipTest { + + static boolean passed = true; + + static boolean checkImage(BufferedImage img, int clipY) { + for (int y = clipY; y < img.getHeight(); y++) { + for (int x = 0; x < img.getWidth(); x++) { + if ((img.getRGB(x,y) & 0xFFFFFF) != 0xFFFFFF) { + return false; + } + } + } + return true; + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree"); + DefaultMutableTreeNode parent; + + parent = new DefaultMutableTreeNode("colors"); + root.add(parent); + parent.add(new DefaultMutableTreeNode("blue")); + DefaultTreeModel model = new DefaultTreeModel(root); + JTree tree = new JTree(model); + + BufferedImage img = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB); + for (int clipY = 1; clipY < 50; clipY++) { + Graphics2D ig = img.createGraphics(); + ig.setColor(Color.WHITE); + ig.fillRect(0,0,1000, 1000); + tree.setSize(200,200); + ig.setClip(0,0,1000,clipY); + tree.paint(ig); + ig.dispose(); + + if (!checkImage(img, clipY)) { + System.err.println("Failed with clipY=" + clipY); + passed = false; + try { + ImageIO.write(img, "PNG", new File("failedResult.png")); + } catch (IOException e) { + e.printStackTrace(); + } + return; + } + } + } + }); + + if (!passed) { + throw new RuntimeException("Test failed."); + } else { + System.out.println("Passed."); + } + } +} \ No newline at end of file diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/jdk/lambda/separate/Compiler.java --- a/jdk/test/jdk/lambda/separate/Compiler.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/jdk/lambda/separate/Compiler.java Thu Mar 05 15:23:22 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ private static final AtomicInteger counter = new AtomicInteger(); private static final String targetDir = System.getProperty("lambda.separate.targetDirectory", - System.getProperty("java.io.tmpdir") + File.separator + "gen-separate"); + "." + File.separator + "gen-separate"); private static final File root = new File(targetDir); private static ConcurrentHashMap cache = new ConcurrentHashMap<>(); @@ -189,7 +189,7 @@ StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); } catch (IOException e) { throw new RuntimeException( - "IOException encountered during compilation"); + "IOException encountered during compilation: " + e.getMessage(), e); } Boolean result = ct.call(); if (result == Boolean.FALSE) { diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelauncher/ProgramTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelauncher/ProgramTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @library /lib/testlibrary + * @build jdk.testlibrary.OutputAnalyzer + * @build ProgramTest + * @run main/native ProgramTest + */ + +import jdk.testlibrary.OutputAnalyzer; +import jdk.testlibrary.ProcessTools; + +public class ProgramTest { + public static void main(String... args) throws Exception { + String lib = System.getProperty("test.nativepath"); + ProcessBuilder pb = new ProcessBuilder(lib + "/sanity_SimpleNativeLauncher"); + OutputAnalyzer output = ProcessTools.executeProcess(pb); + output.shouldHaveExitValue(0); + output.stdoutShouldContain("Hello"); + } +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelauncher/exesanity_SimpleNativeLauncher.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelauncher/exesanity_SimpleNativeLauncher.c Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + #include + +int +main(int argc, char** argv) +{ + printf("Hello\n"); + return 0; +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelib/NativeLib.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelib/NativeLib.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @run main/native NativeLib + */ + +public class NativeLib { + public static void main(String... args) throws Exception { + System.loadLibrary("sanity_SimpleNativeLib"); + + int res = nativeFunc(); + if (res != 4711) { + throw new Exception("Wrong value returned from native code: " + res); + } + } + + static native int nativeFunc(); +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelib/libsanity_SimpleNativeLib.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelib/libsanity_SimpleNativeLib.c Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + #include + +JNIEXPORT jint JNICALL +Java_NativeLib_nativeFunc(JNIEnv *env, jclass dummy) +{ + return 4711; +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelib2/NativeLib.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelib2/NativeLib.java Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* + * @test + * @run main/native NativeLib + */ + +public class NativeLib { + public static void main(String... args) throws Exception { + System.loadLibrary("sanity_SimpleNativeLib2"); + + int res = nativeFunc(); + if (res != 4712) { + throw new Exception("Wrong value returned from native code: " + res); + } + } + + static native int nativeFunc(); +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/native_sanity/simplenativelib2/libsanity_SimpleNativeLib2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/native_sanity/simplenativelib2/libsanity_SimpleNativeLib2.c Thu Mar 05 15:23:22 2015 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + #include + +JNIEXPORT jint JNICALL +Java_NativeLib_nativeFunc(JNIEnv *env, jclass dummy) +{ + return 4712; +} diff -r 4f62c57aef4e -r 690957fb0862 jdk/test/sun/security/tools/keytool/KeyToolTest.java --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java Thu Mar 05 11:26:17 2015 -0800 +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java Thu Mar 05 15:23:22 2015 -0800 @@ -1612,7 +1612,7 @@ // 8073181: keytool -ext honored not working correctly testOK("", simple+"-gencert -alias ca -infile test.req -ext " + - "honored=1.2.3,1.2.4:critical " + + "honored=1.2.3,KU,1.2.4:critical " + "-debug -rfc -outfile test2.cert"); testOK("", simple+"-importcert -file test2.cert -alias b"); ks = loadStore("x.jks", "changeit", "JKS");