Mercurial > hg > openjdk > aarch64-port > jdk
changeset 7985:3575263eefab
Merge
author | mullan |
---|---|
date | Tue, 27 Aug 2013 12:27:31 -0400 |
parents | 6a1bfcde4d4d (current diff) 134283a88499 (diff) |
children | 51151b440e95 |
files | src/share/classes/com/sun/security/auth/PolicyParser.java src/share/classes/com/sun/security/auth/SubjectCodeSource.java src/share/classes/sun/misc/Compare.java src/share/classes/sun/misc/Sort.java |
diffstat | 152 files changed, 6922 insertions(+), 3822 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Aug 27 12:04:32 2013 -0400 +++ b/.hgtags Tue Aug 27 12:27:31 2013 -0400 @@ -224,3 +224,5 @@ 5be9c5bfcfe9b2a40412b4fb364377d49de014eb jdk8-b100 6901612328239fbd471d20823113c1cf3fdaebee jdk8-b101 8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102 +e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 +f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
--- a/make/com/sun/security/auth/FILES_java.gmk Tue Aug 27 12:04:32 2013 -0400 +++ b/make/com/sun/security/auth/FILES_java.gmk Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ # -# Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 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 @@ -43,8 +43,6 @@ com/sun/security/auth/UserPrincipal.java \ com/sun/security/auth/LdapPrincipal.java \ com/sun/security/auth/PolicyFile.java \ - com/sun/security/auth/SubjectCodeSource.java \ - com/sun/security/auth/PolicyParser.java \ com/sun/security/auth/PrincipalComparator.java \ com/sun/security/auth/callback/TextCallbackHandler.java \ com/sun/security/auth/callback/DialogCallbackHandler.java
--- a/make/java/java/mapfile-vers Tue Aug 27 12:04:32 2013 -0400 +++ b/make/java/java/mapfile-vers Tue Aug 27 12:27:31 2013 -0400 @@ -100,7 +100,7 @@ Java_java_io_RandomAccessFile_open; Java_java_io_RandomAccessFile_read; Java_java_io_RandomAccessFile_readBytes; - Java_java_io_RandomAccessFile_seek; + Java_java_io_RandomAccessFile_seek0; Java_java_io_RandomAccessFile_setLength; Java_java_io_RandomAccessFile_write; Java_java_io_RandomAccessFile_writeBytes;
--- a/make/sun/jconsole/Makefile Tue Aug 27 12:04:32 2013 -0400 +++ b/make/sun/jconsole/Makefile Tue Aug 27 12:27:31 2013 -0400 @@ -94,4 +94,5 @@ clean clobber:: $(RM) $(TEMPDIR)/manifest $(JARFILE) + $(RM) $(GENSRCDIR)/sun/tools/jconsole/Version.java
--- a/makefiles/CompileNativeLibraries.gmk Tue Aug 27 12:04:32 2013 -0400 +++ b/makefiles/CompileNativeLibraries.gmk Tue Aug 27 12:27:31 2013 -0400 @@ -199,7 +199,7 @@ LIBJAVA_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \ -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \ -DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \ - -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' + -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' ifneq (,$(JDK_UPDATE_VERSION)) LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' @@ -279,7 +279,7 @@ BUILD_LIBMLIB_SRC:=$(JDK_TOPDIR)/src/share/native/sun/awt/medialib BUILD_LIBMLIB_CFLAGS:=-D__USE_J2D_NAMES -D__MEDIALIB_OLD_NAMES \ -I$(BUILD_LIBMLIB_SRC) \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/medialib BUILD_LIBMLIB_LDLIBS:= BUILD_LIBMLIB_IMAGE_MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libmlib_image/mapfile-vers @@ -1042,6 +1042,7 @@ LANG:=C,\ OPTIMIZATION:=LOW, \ CFLAGS:=$(CFLAGS_JDKLIB),\ + CFLAGS_windows:=/Gy,\ MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \ VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\ RC_FLAGS:=$(RC_FLAGS) \ @@ -1051,6 +1052,7 @@ LDFLAGS:=$(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN),\ LDFLAGS_solaris:=-ldoor,\ + LDFLAGS_windows:=/ORDER:@$(JDK_TOPDIR)/makefiles/mapfiles/libattach/reorder-windows-$(OPENJDK_TARGET_CPU),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\ LDFLAGS_SUFFIX_windows:=$(WIN_JAVA_LIB) advapi32.lib psapi.lib,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libattach,\ @@ -1413,10 +1415,10 @@ # ifeq ($(OPENJDK_TARGET_OS), linux) # ifeq ("$(CC_VER_MAJOR)", "3") # OTHER_LDLIBS += -Wl,-Bstatic -lgcc_eh -Wl,-Bdynamic -# endif +# endif # endif # -# The resulting size of the t2k lib file is (at least on linux) dependant on the order of +# The resulting size of the t2k lib file is (at least on linux) dependant on the order of # the input .o files. Because of this the new build will differ in size to the old build. BUILD_LIBT2K_CFLAGS_COMMON:=-I$(JDK_TOPDIR)/src/share/native/sun/font \ -I$(JDK_TOPDIR)/src/closed/share/native/sun/font/t2k \ @@ -1590,8 +1592,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows) LIBINSTRUMENT_LDFLAGS += $(JDK_OUTPUTDIR)/objs/jli_static.lib $(WIN_JAVA_LIB) \ -export:Agent_OnAttach advapi32.lib - # Statically link the C runtime so that there are not dependencies on modules - # not on the search patch when invoked from the Windows system directory + # Statically link the C runtime so that there are not dependencies on modules + # not on the search patch when invoked from the Windows system directory # (or elsewhere). LIBINSTRUMENT_CFLAGS := $(filter-out -MD,$(LIBINSTRUMENT_CFLAGS)) # equivalent of strcasecmp is stricmp on Windows @@ -2065,13 +2067,13 @@ ifeq ($(OPENJDK_TARGET_OS), windows) BUILD_LIBJLI_FILES += java_md.c \ - cmdtoargs.c + cmdtoargs.c # Staticically link with c runtime on windows. LIBJLI_CFLAGS:=$(filter-out -MD,$(LIBJLI_CFLAGS)) else ifneq ($(OPENJDK_TARGET_OS), macosx) BUILD_LIBJLI_FILES += java_md_common.c - BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c + BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c @@ -2518,7 +2520,7 @@ BUILD_LIBRARIES += $(LIBSPLASHSCREEN) ifeq ($(OPENJDK_TARGET_OS),macosx) -$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) +$(LIBSPLASHSCREEN) : $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)osxapp$(SHARED_LIBRARY_SUFFIX) endif endif @@ -3246,7 +3248,7 @@ BUILD_LIBRARIES += $(BUILD_LIBAWT_LWAWT) -$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT) +$(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBAWT) $(BUILD_LIBAWT_LWAWT) : $(BUILD_LIBMLIB_IMAGE) @@ -3287,7 +3289,7 @@ BUILD_LIBRARIES += $(BUILD_LIBOSXUI) -$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT) +$(BUILD_LIBOSXUI) : $(BUILD_LIBAWT) $(BUILD_LIBOSXUI) : $(BUILD_LIBOSXAPP)
--- a/makefiles/Profiles.gmk Tue Aug 27 12:04:32 2013 -0400 +++ b/makefiles/Profiles.gmk Tue Aug 27 12:27:31 2013 -0400 @@ -65,10 +65,6 @@ $(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \ $(PROFILE_1_JARS) -ifneq ($(ENABLE_JFR), true) - PROFILE_3_JRE_JAR_FILES := $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES)) -endif - PROFILE_3_JARS := \ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \ $(PROFILE_2_JARS) @@ -77,6 +73,10 @@ FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES)) endif +ifneq ($(ENABLE_JFR), true) + FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES)) +endif + FULL_JRE_JARS := \ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \ $(PROFILE_3_JARS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefiles/mapfiles/libattach/reorder-windows-x86 Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,2 @@ +jvm_attach_thread_func@4 +jvm_attach_thread_func_end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/makefiles/mapfiles/libattach/reorder-windows-x86_64 Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,2 @@ +jvm_attach_thread_func +jvm_attach_thread_func_end
--- a/makefiles/mapfiles/libjava/mapfile-vers Tue Aug 27 12:04:32 2013 -0400 +++ b/makefiles/mapfiles/libjava/mapfile-vers Tue Aug 27 12:27:31 2013 -0400 @@ -100,7 +100,7 @@ Java_java_io_RandomAccessFile_open; Java_java_io_RandomAccessFile_read; Java_java_io_RandomAccessFile_readBytes; - Java_java_io_RandomAccessFile_seek; + Java_java_io_RandomAccessFile_seek0; Java_java_io_RandomAccessFile_setLength; Java_java_io_RandomAccessFile_write; Java_java_io_RandomAccessFile_writeBytes;
--- a/makefiles/profile-includes.txt Tue Aug 27 12:04:32 2013 -0400 +++ b/makefiles/profile-includes.txt Tue Aug 27 12:27:31 2013 -0400 @@ -102,6 +102,7 @@ security/US_export_policy.jar \ security/local_policy.jar + PROFILE_2_JRE_BIN_FILES := \ rmid$(EXE_SUFFIX) \ rmiregistry$(EXE_SUFFIX) @@ -140,7 +141,6 @@ PROFILE_3_JRE_OTHER_FILES := PROFILE_3_JRE_JAR_FILES := \ - jfr.jar \ management-agent.jar @@ -253,6 +253,6 @@ ext/cldrdata.jar \ ext/dnsns.jar \ ext/nashorn.jar \ - ext/zipfs.jar + ext/zipfs.jar \ + jfr.jar -
--- a/src/macosx/native/sun/awt/CMenuItem.m Tue Aug 27 12:04:32 2013 -0400 +++ b/src/macosx/native/sun/awt/CMenuItem.m Tue Aug 27 12:27:31 2013 -0400 @@ -296,7 +296,7 @@ case java_awt_event_KeyEvent_VK_HELP : macKey = NSHelpFunctionKey; break; case java_awt_event_KeyEvent_VK_TAB : macKey = NSTabCharacter; break; - case java_awt_event_KeyEvent_VK_ENTER : macKey = NSCarriageReturnCharacter; break; + case java_awt_event_KeyEvent_VK_ENTER : macKey = NSNewlineCharacter; break; case java_awt_event_KeyEvent_VK_BACK_SPACE : macKey = NSBackspaceCharacter; break; case java_awt_event_KeyEvent_VK_DELETE : macKey = NSDeleteCharacter; break; case java_awt_event_KeyEvent_VK_CLEAR : macKey = NSClearDisplayFunctionKey; break;
--- a/src/share/classes/com/sun/media/sound/DataPusher.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/media/sound/DataPusher.java Tue Aug 27 12:27:31 2013 -0400 @@ -25,6 +25,8 @@ package com.sun.media.sound; +import java.util.Arrays; + import javax.sound.sampled.*; /** @@ -46,11 +48,11 @@ private final AudioFormat format; // stream as source data - private AudioInputStream ais = null; + private final AudioInputStream ais; // byte array as source data - private byte[] audioData = null; - private int audioDataByteLength = 0; + private final byte[] audioData; + private final int audioDataByteLength; private int pos; private int newPos = -1; private boolean looping; @@ -67,16 +69,22 @@ private final int BUFFER_SIZE = 16384; public DataPusher(SourceDataLine sourceLine, AudioFormat format, byte[] audioData, int byteLength) { - this.audioData = audioData; - this.audioDataByteLength = byteLength; - this.format = format; - this.source = sourceLine; + this(sourceLine, format, null, audioData, byteLength); } public DataPusher(SourceDataLine sourceLine, AudioInputStream ais) { + this(sourceLine, ais.getFormat(), ais, null, 0); + } + + private DataPusher(final SourceDataLine source, final AudioFormat format, + final AudioInputStream ais, final byte[] audioData, + final int audioDataByteLength) { + this.source = source; + this.format = format; this.ais = ais; - this.format = ais.getFormat(); - this.source = sourceLine; + this.audioDataByteLength = audioDataByteLength; + this.audioData = audioData == null ? null : Arrays.copyOf(audioData, + audioData.length); } public synchronized void start() {
--- a/src/share/classes/com/sun/media/sound/ModelStandardDirector.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/media/sound/ModelStandardDirector.java Tue Aug 27 12:27:31 2013 -0400 @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import java.util.Arrays; + /** * A standard director who chooses performers * by there keyfrom,keyto,velfrom,velto properties. @@ -32,17 +34,16 @@ */ public final class ModelStandardDirector implements ModelDirector { - ModelPerformer[] performers; - ModelDirectedPlayer player; - boolean noteOnUsed = false; - boolean noteOffUsed = false; + private final ModelPerformer[] performers; + private final ModelDirectedPlayer player; + private boolean noteOnUsed = false; + private boolean noteOffUsed = false; - public ModelStandardDirector(ModelPerformer[] performers, - ModelDirectedPlayer player) { - this.performers = performers; + public ModelStandardDirector(final ModelPerformer[] performers, + final ModelDirectedPlayer player) { + this.performers = Arrays.copyOf(performers, performers.length); this.player = player; - for (int i = 0; i < performers.length; i++) { - ModelPerformer p = performers[i]; + for (final ModelPerformer p : this.performers) { if (p.isReleaseTriggered()) { noteOffUsed = true; } else {
--- a/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/media/sound/ModelStandardIndexedDirector.java Tue Aug 27 12:27:31 2013 -0400 @@ -24,6 +24,8 @@ */ package com.sun.media.sound; +import java.util.Arrays; + /** * A standard indexed director who chooses performers * by there keyfrom,keyto,velfrom,velto properties. @@ -32,22 +34,21 @@ */ public final class ModelStandardIndexedDirector implements ModelDirector { - ModelPerformer[] performers; - ModelDirectedPlayer player; - boolean noteOnUsed = false; - boolean noteOffUsed = false; + private final ModelPerformer[] performers; + private final ModelDirectedPlayer player; + private boolean noteOnUsed = false; + private boolean noteOffUsed = false; // Variables needed for index - byte[][] trantables; - int[] counters; - int[][] mat; + private byte[][] trantables; + private int[] counters; + private int[][] mat; - public ModelStandardIndexedDirector(ModelPerformer[] performers, - ModelDirectedPlayer player) { - this.performers = performers; + public ModelStandardIndexedDirector(final ModelPerformer[] performers, + final ModelDirectedPlayer player) { + this.performers = Arrays.copyOf(performers, performers.length); this.player = player; - for (int i = 0; i < performers.length; i++) { - ModelPerformer p = performers[i]; + for (final ModelPerformer p : this.performers) { if (p.isReleaseTriggered()) { noteOffUsed = true; } else {
--- a/src/share/classes/com/sun/media/sound/SoftMixingClip.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/media/sound/SoftMixingClip.java Tue Aug 27 12:27:31 2013 -0400 @@ -38,7 +38,7 @@ import javax.sound.sampled.LineUnavailableException; /** - * Clip implemention for the SoftMixingMixer. + * Clip implementation for the SoftMixingMixer. * * @author Karl Helgason */ @@ -357,7 +357,9 @@ throw new IllegalArgumentException( "Buffer size does not represent an integral number of sample frames!"); - this.data = data; + if (data != null) { + this.data = Arrays.copyOf(data, data.length); + } this.offset = offset; this.bufferSize = bufferSize; this.format = format;
--- a/src/share/classes/com/sun/security/auth/PolicyFile.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/security/auth/PolicyFile.java Tue Aug 27 12:27:31 2013 -0400 @@ -25,31 +25,9 @@ package com.sun.security.auth; -import java.io.*; -import java.lang.reflect.*; -import java.net.URL; -import java.util.*; - import java.security.CodeSource; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.Permission; -import java.security.Permissions; import java.security.PermissionCollection; -import java.security.Principal; -import java.security.UnresolvedPermission; -import java.security.Security; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; - import javax.security.auth.Subject; -import javax.security.auth.PrivateCredentialPermission; - -import sun.security.util.PropertyExpander; - -import sun.security.provider.PolicyParser.PrincipalEntry; -import sun.security.provider.PolicyParser.GrantEntry; -import sun.security.provider.PolicyParser.PermissionEntry; /** * This class represents a default implementation for @@ -240,61 +218,14 @@ @Deprecated public class PolicyFile extends javax.security.auth.Policy { - static final java.util.ResourceBundle rb = - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<java.util.ResourceBundle>() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.AuthResources")); - } - }); - // needs to be package private - - private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance("policy", "\t[Auth Policy]"); - - private static final String AUTH_POLICY = "java.security.auth.policy"; - private static final String SECURITY_MANAGER = "java.security.manager"; - private static final String AUTH_POLICY_URL = "auth.policy.url."; - - private Vector<PolicyEntry> policyEntries; - private Hashtable<Object, Object> aliasMapping; - - private boolean initialized = false; - - private boolean expandProperties = true; - private boolean ignoreIdentityScope = true; - - // for use with the reflection API - - private static final Class[] PARAMS = { String.class, String.class}; + private final sun.security.provider.AuthPolicyFile apf; /** * Initializes the Policy object and reads the default policy * configuration file(s) into the Policy object. */ public PolicyFile() { - // initialize Policy if either the AUTH_POLICY or - // SECURITY_MANAGER properties are set - String prop = System.getProperty(AUTH_POLICY); - - if (prop == null) { - prop = System.getProperty(SECURITY_MANAGER); - } - if (prop != null) - init(); - } - - private synchronized void init() { - - if (initialized) - return; - - policyEntries = new Vector<PolicyEntry>(); - aliasMapping = new Hashtable<Object, Object>(11); - - initPolicyFile(); - initialized = true; + apf = new sun.security.provider.AuthPolicyFile(); } /** @@ -305,460 +236,9 @@ * @exception SecurityException if the caller doesn't have permission * to refresh the <code>Policy</code>. */ - public synchronized void refresh() - { - - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new javax.security.auth.AuthPermission - ("refreshPolicy")); - } - - // XXX - // - // 1) if code instantiates PolicyFile directly, then it will need - // all the permissions required for the PolicyFile initialization - // 2) if code calls Policy.getPolicy, then it simply needs - // AuthPermission(getPolicy), and the javax.security.auth.Policy - // implementation instantiates PolicyFile in a doPrivileged block - // 3) if after instantiating a Policy (either via #1 or #2), - // code calls refresh, it simply needs - // AuthPermission(refreshPolicy). then PolicyFile wraps - // the refresh in a doPrivileged block. - initialized = false; - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<Void>() { - public Void run() { - init(); - return null; - } - }); - } - - private KeyStore initKeyStore(URL policyUrl, String keyStoreName, - String keyStoreType) { - if (keyStoreName != null) { - try { - /* - * location of keystore is specified as absolute URL in policy - * file, or is relative to URL of policy file - */ - URL keyStoreUrl = null; - try { - keyStoreUrl = new URL(keyStoreName); - // absolute URL - } catch (java.net.MalformedURLException e) { - // relative URL - keyStoreUrl = new URL(policyUrl, keyStoreName); - } - - if (debug != null) { - debug.println("reading keystore"+keyStoreUrl); - } - - InputStream inStream = - new BufferedInputStream(getInputStream(keyStoreUrl)); - - KeyStore ks; - if (keyStoreType != null) - ks = KeyStore.getInstance(keyStoreType); - else - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(inStream, null); - inStream.close(); - return ks; - } catch (Exception e) { - // ignore, treat it like we have no keystore - if (debug != null) { - e.printStackTrace(); - } - return null; - } - } - return null; - } - - private void initPolicyFile() { - - String prop = Security.getProperty("policy.expandProperties"); - - if (prop != null) expandProperties = prop.equalsIgnoreCase("true"); - - String iscp = Security.getProperty("policy.ignoreIdentityScope"); - - if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true"); - - String allowSys = Security.getProperty("policy.allowSystemProperty"); - - if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) { - - String extra_policy = System.getProperty(AUTH_POLICY); - if (extra_policy != null) { - boolean overrideAll = false; - if (extra_policy.startsWith("=")) { - overrideAll = true; - extra_policy = extra_policy.substring(1); - } - try { - extra_policy = PropertyExpander.expand(extra_policy); - URL policyURL; - File policyFile = new File(extra_policy); - if (policyFile.exists()) { - policyURL = - new URL("file:" + policyFile.getCanonicalPath()); - } else { - policyURL = new URL(extra_policy); - } - if (debug != null) - debug.println("reading "+policyURL); - init(policyURL); - } catch (Exception e) { - // ignore. - if (debug != null) { - debug.println("caught exception: "+e); - } - - } - if (overrideAll) { - if (debug != null) { - debug.println("overriding other policies!"); - } - return; - } - } - } - - int n = 1; - boolean loaded_one = false; - String policy_url; - - while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) { - try { - policy_url = PropertyExpander.expand(policy_url).replace - (File.separatorChar, '/'); - if (debug != null) - debug.println("reading "+policy_url); - init(new URL(policy_url)); - loaded_one = true; - } catch (Exception e) { - if (debug != null) { - debug.println("error reading policy "+e); - e.printStackTrace(); - } - // ignore that policy - } - n++; - } - - if (loaded_one == false) { - // do not load a static policy - } - } - - /** - * Checks public key. If it is marked as trusted in - * the identity database, add it to the policy - * with the AllPermission. - */ - private boolean checkForTrustedIdentity(final Certificate cert) { - // XXX JAAS has no way to access the SUN package. - // we'll add this back in when JAAS goes into core. - return false; - } - - /** - * Reads a policy configuration into the Policy object using a - * Reader object. - * - * @param policyFile the policy Reader object. - */ - private void init(URL policy) { - sun.security.provider.PolicyParser pp = - new sun.security.provider.PolicyParser(expandProperties); - try { - InputStreamReader isr - = new InputStreamReader(getInputStream(policy)); - pp.read(isr); - isr.close(); - KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), - pp.getKeyStoreType()); - Enumeration<GrantEntry> enum_ = pp.grantElements(); - while (enum_.hasMoreElements()) { - GrantEntry ge = enum_.nextElement(); - addGrantEntry(ge, keyStore); - } - } catch (sun.security.provider.PolicyParser.ParsingException pe) { - System.err.println(AUTH_POLICY + - rb.getString(".error.parsing.") + policy); - System.err.println(AUTH_POLICY + - rb.getString("COLON") + - pe.getMessage()); - if (debug != null) - pe.printStackTrace(); - - } catch (Exception e) { - if (debug != null) { - debug.println("error parsing "+policy); - debug.println(e.toString()); - e.printStackTrace(); - } - } - } - - /* - * Fast path reading from file urls in order to avoid calling - * FileURLConnection.connect() which can be quite slow the first time - * it is called. We really should clean up FileURLConnection so that - * this is not a problem but in the meantime this fix helps reduce - * start up time noticeably for the new launcher. -- DAC - */ - private InputStream getInputStream(URL url) throws IOException { - if ("file".equals(url.getProtocol())) { - String path = url.getFile().replace('/', File.separatorChar); - return new FileInputStream(path); - } else { - return url.openStream(); - } - } - - /** - * Given a PermissionEntry, create a codeSource. - * - * @return null if signedBy alias is not recognized - */ - CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) - throws java.net.MalformedURLException - { - Certificate[] certs = null; - if (ge.signedBy != null) { - certs = getCertificates(keyStore, ge.signedBy); - if (certs == null) { - // we don't have a key for this alias, - // just return - if (debug != null) { - debug.println(" no certs for alias " + - ge.signedBy + ", ignoring."); - } - return null; - } - } - - URL location; - - if (ge.codeBase != null) - location = new URL(ge.codeBase); - else - location = null; - - if (ge.principals == null || ge.principals.size() == 0) { - return (canonicalizeCodebase - (new CodeSource(location, certs), - false)); - } else { - return (canonicalizeCodebase - (new SubjectCodeSource(null, ge.principals, location, certs), - false)); - } - } - - /** - * Add one policy entry to the vector. - */ - private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { - - if (debug != null) { - debug.println("Adding policy entry: "); - debug.println(" signedBy " + ge.signedBy); - debug.println(" codeBase " + ge.codeBase); - if (ge.principals != null && ge.principals.size() > 0) { - ListIterator<PrincipalEntry> li = ge.principals.listIterator(); - while (li.hasNext()) { - PrincipalEntry pppe = li.next(); - debug.println(" " + pppe.getPrincipalClass() + - " " + pppe.getPrincipalName()); - } - } - debug.println(); - } - - try { - CodeSource codesource = getCodeSource(ge, keyStore); - // skip if signedBy alias was unknown... - if (codesource == null) return; - - PolicyEntry entry = new PolicyEntry(codesource); - Enumeration<PermissionEntry> enum_ = ge.permissionElements(); - while (enum_.hasMoreElements()) { - PermissionEntry pe = enum_.nextElement(); - try { - // XXX special case PrivateCredentialPermission-SELF - Permission perm; - if (pe.permission.equals - ("javax.security.auth.PrivateCredentialPermission") && - pe.name.endsWith(" self")) { - perm = getInstance(pe.permission, - pe.name + " \"self\"", - pe.action); - } else { - perm = getInstance(pe.permission, - pe.name, - pe.action); - } - entry.add(perm); - if (debug != null) { - debug.println(" "+perm); - } - } catch (ClassNotFoundException cnfe) { - Certificate certs[]; - if (pe.signedBy != null) - certs = getCertificates(keyStore, pe.signedBy); - else - certs = null; - - // only add if we had no signer or we had a - // a signer and found the keys for it. - if (certs != null || pe.signedBy == null) { - Permission perm = new UnresolvedPermission( - pe.permission, - pe.name, - pe.action, - certs); - entry.add(perm); - if (debug != null) { - debug.println(" "+perm); - } - } - } catch (java.lang.reflect.InvocationTargetException ite) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Permission.") + - pe.permission + - rb.getString("SPACE") + - ite.getTargetException()); - } catch (Exception e) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Permission.") + - pe.permission + - rb.getString("SPACE") + - e); - } - } - policyEntries.addElement(entry); - } catch (Exception e) { - System.err.println - (AUTH_POLICY + - rb.getString(".error.adding.Entry.") + - ge + - rb.getString("SPACE") + - e); - } - - if (debug != null) - debug.println(); - } - - /** - * Returns a new Permission object of the given Type. The Permission is - * created by getting the - * Class object using the <code>Class.forName</code> method, and using - * the reflection API to invoke the (String name, String actions) - * constructor on the - * object. - * - * @param type the type of Permission being created. - * @param name the name of the Permission being created. - * @param actions the actions of the Permission being created. - * - * @exception ClassNotFoundException if the particular Permission - * class could not be found. - * - * @exception IllegalAccessException if the class or initializer is - * not accessible. - * - * @exception InstantiationException if getInstance tries to - * instantiate an abstract class or an interface, or if the - * instantiation fails for some other reason. - * - * @exception NoSuchMethodException if the (String, String) constructor - * is not found. - * - * @exception InvocationTargetException if the underlying Permission - * constructor throws an exception. - * - */ - - private static final Permission getInstance(String type, - String name, - String actions) - throws ClassNotFoundException, - InstantiationException, - IllegalAccessException, - NoSuchMethodException, - InvocationTargetException - { - //XXX we might want to keep a hash of created factories... - Class<?> pc = Class.forName(type); - Constructor<?> c = pc.getConstructor(PARAMS); - return (Permission) c.newInstance(new Object[] { name, actions }); - } - - /** - * Fetch all certs associated with this alias. - */ - Certificate[] getCertificates( - KeyStore keyStore, String aliases) { - - Vector<Certificate> vcerts = null; - - StringTokenizer st = new StringTokenizer(aliases, ","); - int n = 0; - - while (st.hasMoreTokens()) { - String alias = st.nextToken().trim(); - n++; - Certificate cert = null; - //See if this alias's cert has already been cached - cert = (Certificate) aliasMapping.get(alias); - if (cert == null && keyStore != null) { - - try { - cert = keyStore.getCertificate(alias); - } catch (KeyStoreException kse) { - // never happens, because keystore has already been loaded - // when we call this - } - if (cert != null) { - aliasMapping.put(alias, cert); - aliasMapping.put(cert, alias); - } - } - - if (cert != null) { - if (vcerts == null) - vcerts = new Vector<Certificate>(); - vcerts.addElement(cert); - } - } - - // make sure n == vcerts.size, since we are doing a logical *and* - if (vcerts != null && n == vcerts.size()) { - Certificate[] certs = new Certificate[vcerts.size()]; - vcerts.copyInto(certs); - return certs; - } else { - return null; - } - } - - /** - * Enumerate all the entries in the global policy object. - * This method is used by policy admin tools. The tools - * should use the Enumeration methods on the returned object - * to fetch the elements sequentially. - */ - private final synchronized Enumeration<PolicyEntry> elements(){ - return policyEntries.elements(); + @Override + public void refresh() { + apf.refresh(); } /** @@ -816,646 +296,9 @@ * @return the Permissions granted to the provided <code>Subject</code> * <code>CodeSource</code>. */ + @Override public PermissionCollection getPermissions(final Subject subject, - final CodeSource codesource) { - - // XXX when JAAS goes into the JDK core, - // we can remove this method and simply - // rely on the getPermissions variant that takes a codesource, - // which no one can use at this point in time. - // at that time, we can also make SubjectCodeSource a public - // class. - - // XXX - // - // 1) if code instantiates PolicyFile directly, then it will need - // all the permissions required for the PolicyFile initialization - // 2) if code calls Policy.getPolicy, then it simply needs - // AuthPermission(getPolicy), and the javax.security.auth.Policy - // implementation instantiates PolicyFile in a doPrivileged block - // 3) if after instantiating a Policy (either via #1 or #2), - // code calls getPermissions, PolicyFile wraps the call - // in a doPrivileged block. - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<PermissionCollection>() { - public PermissionCollection run() { - SubjectCodeSource scs = new SubjectCodeSource - (subject, - null, - codesource == null ? null : codesource.getLocation(), - codesource == null ? null : codesource.getCertificates()); - if (initialized) - return getPermissions(new Permissions(), scs); - else - return new PolicyPermissions(PolicyFile.this, scs); - } - }); - } - - /** - * Examines the global policy for the specified CodeSource, and - * creates a PermissionCollection object with - * the set of permissions for that principal's protection domain. - * - * @param CodeSource the codesource associated with the caller. - * This encapsulates the original location of the code (where the code - * came from) and the public key(s) of its signer. - * - * @return the set of permissions according to the policy. - */ - PermissionCollection getPermissions(CodeSource codesource) { - - if (initialized) - return getPermissions(new Permissions(), codesource); - else - return new PolicyPermissions(this, codesource); - } - - /** - * Examines the global policy for the specified CodeSource, and - * creates a PermissionCollection object with - * the set of permissions for that principal's protection domain. - * - * @param permissions the permissions to populate - * @param codesource the codesource associated with the caller. - * This encapsulates the original location of the code (where the code - * came from) and the public key(s) of its signer. - * - * @return the set of permissions according to the policy. - */ - Permissions getPermissions(final Permissions perms, - final CodeSource cs) - { - if (!initialized) { - init(); - } - - final CodeSource codesource[] = {null}; - - codesource[0] = canonicalizeCodebase(cs, true); - - if (debug != null) { - debug.println("evaluate("+codesource[0]+")\n"); - } - - // needs to be in a begin/endPrivileged block because - // codesource.implies calls URL.equals which does an - // InetAddress lookup - - for (int i = 0; i < policyEntries.size(); i++) { - - PolicyEntry entry = policyEntries.elementAt(i); - - if (debug != null) { - debug.println("PolicyFile CodeSource implies: " + - entry.codesource.toString() + "\n\n" + - "\t" + codesource[0].toString() + "\n\n"); - } - - if (entry.codesource.implies(codesource[0])) { - for (int j = 0; j < entry.permissions.size(); j++) { - Permission p = entry.permissions.elementAt(j); - if (debug != null) { - debug.println(" granting " + p); - } - if (!addSelfPermissions(p, entry.codesource, - codesource[0], perms)) { - // we could check for duplicates - // before adding new permissions, - // but the SubjectDomainCombiner - // already checks for duplicates later - perms.add(p); - } - } - } - } - - // now see if any of the keys are trusted ids. - - if (!ignoreIdentityScope) { - Certificate certs[] = codesource[0].getCertificates(); - if (certs != null) { - for (int k=0; k < certs.length; k++) { - if ((aliasMapping.get(certs[k]) == null) && - checkForTrustedIdentity(certs[k])) { - // checkForTrustedIdentity added it - // to the policy for us. next time - // around we'll find it. This time - // around we need to add it. - perms.add(new java.security.AllPermission()); - } - } - } - } - return perms; - } - - /** - * Returns true if 'Self' permissions were added to the provided - * 'perms', and false otherwise. - * - * <p> - * - * @param p check to see if this Permission is a "SELF" - * PrivateCredentialPermission. <p> - * - * @param entryCs the codesource for the Policy entry. - * - * @param accCs the codesource for from the current AccessControlContext. - * - * @param perms the PermissionCollection where the individual - * PrivateCredentialPermissions will be added. - */ - private boolean addSelfPermissions(final Permission p, - CodeSource entryCs, - CodeSource accCs, - Permissions perms) { - - if (!(p instanceof PrivateCredentialPermission)) - return false; - - if (!(entryCs instanceof SubjectCodeSource)) - return false; - - - PrivateCredentialPermission pcp = (PrivateCredentialPermission)p; - SubjectCodeSource scs = (SubjectCodeSource)entryCs; - - // see if it is a SELF permission - String[][] pPrincipals = pcp.getPrincipals(); - if (pPrincipals.length <= 0 || - !pPrincipals[0][0].equalsIgnoreCase("self") || - !pPrincipals[0][1].equalsIgnoreCase("self")) { - - // regular PrivateCredentialPermission - return false; - } else { - - // granted a SELF permission - create a - // PrivateCredentialPermission for each - // of the Policy entry's CodeSource Principals - - if (scs.getPrincipals() == null) { - // XXX SubjectCodeSource has no Subject??? - return true; - } - - ListIterator<PrincipalEntry> pli = - scs.getPrincipals().listIterator(); - while (pli.hasNext()) { - - PrincipalEntry principal = pli.next(); - - // XXX - // if the Policy entry's Principal does not contain a - // WILDCARD for the Principal name, then a - // new PrivateCredentialPermission is created - // for the Principal listed in the Policy entry. - // if the Policy entry's Principal contains a WILDCARD - // for the Principal name, then a new - // PrivateCredentialPermission is created - // for each Principal associated with the Subject - // in the current ACC. - - String[][] principalInfo = getPrincipalInfo - (principal, accCs); - - for (int i = 0; i < principalInfo.length; i++) { - - // here's the new PrivateCredentialPermission - - PrivateCredentialPermission newPcp = - new PrivateCredentialPermission - (pcp.getCredentialClass() + - " " + - principalInfo[i][0] + - " " + - "\"" + principalInfo[i][1] + "\"", - "read"); - - if (debug != null) { - debug.println("adding SELF permission: " + - newPcp.toString()); - } - - perms.add(newPcp); - } - } - } - return true; - } - - /** - * return the principal class/name pair in the 2D array. - * array[x][y]: x corresponds to the array length. - * if (y == 0), it's the principal class. - * if (y == 1), it's the principal name. - */ - private String[][] getPrincipalInfo - (PrincipalEntry principal, final CodeSource accCs) { - - // there are 3 possibilities: - // 1) the entry's Principal class and name are not wildcarded - // 2) the entry's Principal name is wildcarded only - // 3) the entry's Principal class and name are wildcarded - - if (!principal.getPrincipalClass().equals - (PrincipalEntry.WILDCARD_CLASS) && - !principal.getPrincipalName().equals - (PrincipalEntry.WILDCARD_NAME)) { - - // build a PrivateCredentialPermission for the principal - // from the Policy entry - String[][] info = new String[1][2]; - info[0][0] = principal.getPrincipalClass(); - info[0][1] = principal.getPrincipalName(); - return info; - - } else if (!principal.getPrincipalClass().equals - (PrincipalEntry.WILDCARD_CLASS) && - principal.getPrincipalName().equals - (PrincipalEntry.WILDCARD_NAME)) { - - // build a PrivateCredentialPermission for all - // the Subject's principals that are instances of principalClass - - // the accCs is guaranteed to be a SubjectCodeSource - // because the earlier CodeSource.implies succeeded - SubjectCodeSource scs = (SubjectCodeSource)accCs; - - Set<? extends Principal> principalSet = null; - try { - // principal.principalClass should extend Principal - // If it doesn't, we should stop here with a ClassCastException. - @SuppressWarnings("unchecked") - Class<? extends Principal> pClass = (Class<? extends Principal>) - Class.forName(principal.getPrincipalClass(), false, - ClassLoader.getSystemClassLoader()); - principalSet = scs.getSubject().getPrincipals(pClass); - } catch (Exception e) { - if (debug != null) { - debug.println("problem finding Principal Class " + - "when expanding SELF permission: " + - e.toString()); - } - } - - if (principalSet == null) { - // error - return new String[0][0]; - } - - String[][] info = new String[principalSet.size()][2]; - - int i = 0; - for (Principal p : principalSet) { - info[i][0] = p.getClass().getName(); - info[i][1] = p.getName(); - i++; - } - return info; - - } else { - - // build a PrivateCredentialPermission for every - // one of the current Subject's principals - - // the accCs is guaranteed to be a SubjectCodeSource - // because the earlier CodeSource.implies succeeded - SubjectCodeSource scs = (SubjectCodeSource)accCs; - Set<Principal> principalSet = scs.getSubject().getPrincipals(); - - String[][] info = new String[principalSet.size()][2]; - java.util.Iterator<Principal> pIterator = principalSet.iterator(); - - int i = 0; - while (pIterator.hasNext()) { - Principal p = pIterator.next(); - info[i][0] = p.getClass().getName(); - info[i][1] = p.getName(); - i++; - } - return info; - } - } - - /* - * Returns the signer certificates from the list of certificates associated - * with the given code source. - * - * The signer certificates are those certificates that were used to verify - * signed code originating from the codesource location. - * - * This method assumes that in the given code source, each signer - * certificate is followed by its supporting certificate chain - * (which may be empty), and that the signer certificate and its - * supporting certificate chain are ordered bottom-to-top (i.e., with the - * signer certificate first and the (root) certificate authority last). - */ - Certificate[] getSignerCertificates(CodeSource cs) { - Certificate[] certs = null; - if ((certs = cs.getCertificates()) == null) - return null; - for (int i=0; i<certs.length; i++) { - if (!(certs[i] instanceof X509Certificate)) - return cs.getCertificates(); - } - - // Do we have to do anything? - int i = 0; - int count = 0; - while (i < certs.length) { - count++; - while (((i+1) < certs.length) - && ((X509Certificate)certs[i]).getIssuerDN().equals( - ((X509Certificate)certs[i+1]).getSubjectDN())) { - i++; - } - i++; - } - if (count == certs.length) - // Done - return certs; - - ArrayList<Certificate> userCertList = new ArrayList<>(); - i = 0; - while (i < certs.length) { - userCertList.add(certs[i]); - while (((i+1) < certs.length) - && ((X509Certificate)certs[i]).getIssuerDN().equals( - ((X509Certificate)certs[i+1]).getSubjectDN())) { - i++; - } - i++; - } - Certificate[] userCerts = new Certificate[userCertList.size()]; - userCertList.toArray(userCerts); - return userCerts; - } - - private CodeSource canonicalizeCodebase(CodeSource cs, - boolean extractSignerCerts) { - CodeSource canonCs = cs; - if (cs.getLocation() != null && - cs.getLocation().getProtocol().equalsIgnoreCase("file")) { - try { - String path = cs.getLocation().getFile().replace - ('/', - File.separatorChar); - URL csUrl = null; - if (path.endsWith("*")) { - // remove trailing '*' because it causes canonicalization - // to fail on win32 - path = path.substring(0, path.length()-1); - boolean appendFileSep = false; - if (path.endsWith(File.separator)) - appendFileSep = true; - if (path.equals("")) { - path = System.getProperty("user.dir"); - } - File f = new File(path); - path = f.getCanonicalPath(); - StringBuffer sb = new StringBuffer(path); - // reappend '*' to canonicalized filename (note that - // canonicalization may have removed trailing file - // separator, so we have to check for that, too) - if (!path.endsWith(File.separator) && - (appendFileSep || f.isDirectory())) - sb.append(File.separatorChar); - sb.append('*'); - path = sb.toString(); - } else { - path = new File(path).getCanonicalPath(); - } - csUrl = new File(path).toURL(); - - if (cs instanceof SubjectCodeSource) { - SubjectCodeSource scs = (SubjectCodeSource)cs; - if (extractSignerCerts) { - canonCs = new SubjectCodeSource - (scs.getSubject(), - scs.getPrincipals(), - csUrl, - getSignerCertificates(scs)); - } else { - canonCs = new SubjectCodeSource - (scs.getSubject(), - scs.getPrincipals(), - csUrl, - scs.getCertificates()); - } - } else { - if (extractSignerCerts) { - canonCs = new CodeSource(csUrl, - getSignerCertificates(cs)); - } else { - canonCs = new CodeSource(csUrl, - cs.getCertificates()); - } - } - } catch (IOException ioe) { - // leave codesource as it is, unless we have to extract its - // signer certificates - if (extractSignerCerts) { - if (!(cs instanceof SubjectCodeSource)) { - canonCs = new CodeSource(cs.getLocation(), - getSignerCertificates(cs)); - } else { - SubjectCodeSource scs = (SubjectCodeSource)cs; - canonCs = new SubjectCodeSource(scs.getSubject(), - scs.getPrincipals(), - scs.getLocation(), - getSignerCertificates(scs)); - } - } - } - } else { - if (extractSignerCerts) { - if (!(cs instanceof SubjectCodeSource)) { - canonCs = new CodeSource(cs.getLocation(), - getSignerCertificates(cs)); - } else { - SubjectCodeSource scs = (SubjectCodeSource)cs; - canonCs = new SubjectCodeSource(scs.getSubject(), - scs.getPrincipals(), - scs.getLocation(), - getSignerCertificates(scs)); - } - } - } - return canonCs; - } - - /** - * Each entry in the policy configuration file is represented by a - * PolicyEntry object. <p> - * - * A PolicyEntry is a (CodeSource,Permission) pair. The - * CodeSource contains the (URL, PublicKey) that together identify - * where the Java bytecodes come from and who (if anyone) signed - * them. The URL could refer to localhost. The URL could also be - * null, meaning that this policy entry is given to all comers, as - * long as they match the signer field. The signer could be null, - * meaning the code is not signed. <p> - * - * The Permission contains the (Type, Name, Action) triplet. <p> - * - * For now, the Policy object retrieves the public key from the - * X.509 certificate on disk that corresponds to the signedBy - * alias specified in the Policy config file. For reasons of - * efficiency, the Policy object keeps a hashtable of certs already - * read in. This could be replaced by a secure internal key - * store. - * - * <p> - * For example, the entry - * <pre> - * permission java.io.File "/tmp", "read,write", - * signedBy "Duke"; - * </pre> - * is represented internally - * <pre> - * - * FilePermission f = new FilePermission("/tmp", "read,write"); - * PublicKey p = publickeys.get("Duke"); - * URL u = InetAddress.getLocalHost(); - * CodeBase c = new CodeBase( p, u ); - * pe = new PolicyEntry(f, c); - * </pre> - * - * @author Marianne Mueller - * @author Roland Schemers - * @see java.security.CodeSource - * @see java.security.Policy - * @see java.security.Permissions - * @see java.security.ProtectionDomain - */ - - private static class PolicyEntry { - - CodeSource codesource; - Vector<Permission> permissions; - - /** - * Given a Permission and a CodeSource, create a policy entry. - * - * XXX Decide if/how to add validity fields and "purpose" fields to - * XXX policy entries - * - * @param cs the CodeSource, which encapsulates the URL and the public - * key - * attributes from the policy config file. Validity checks are - * performed on the public key before PolicyEntry is called. - * - */ - PolicyEntry(CodeSource cs) - { - this.codesource = cs; - this.permissions = new Vector<Permission>(); - } - - /** - * add a Permission object to this entry. - */ - void add(Permission p) { - permissions.addElement(p); - } - - /** - * Return the CodeSource for this policy entry - */ - CodeSource getCodeSource() { - return this.codesource; - } - - public String toString(){ - StringBuffer sb = new StringBuffer(); - sb.append(rb.getString("LPARAM")); - sb.append(getCodeSource()); - sb.append("\n"); - for (int j = 0; j < permissions.size(); j++) { - Permission p = permissions.elementAt(j); - sb.append(rb.getString("SPACE")); - sb.append(rb.getString("SPACE")); - sb.append(p); - sb.append(rb.getString("NEWLINE")); - } - sb.append(rb.getString("RPARAM")); - sb.append(rb.getString("NEWLINE")); - return sb.toString(); - } - + final CodeSource codesource) { + return apf.getPermissions(subject, codesource); } } - -@SuppressWarnings("deprecation") -class PolicyPermissions extends PermissionCollection { - - private static final long serialVersionUID = -1954188373270545523L; - - private CodeSource codesource; - private Permissions perms; - private PolicyFile policy; - private boolean notInit; // have we pulled in the policy permissions yet? - private Vector<Permission> additionalPerms; - - PolicyPermissions(PolicyFile policy, - CodeSource codesource) - { - this.codesource = codesource; - this.policy = policy; - this.perms = null; - this.notInit = true; - this.additionalPerms = null; - } - - public void add(Permission permission) { - if (isReadOnly()) - throw new SecurityException - (PolicyFile.rb.getString - ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection")); - - if (perms == null) { - if (additionalPerms == null) - additionalPerms = new Vector<Permission>(); - additionalPerms.add(permission); - } else { - perms.add(permission); - } - } - - private synchronized void init() { - if (notInit) { - if (perms == null) - perms = new Permissions(); - - if (additionalPerms != null) { - Enumeration<Permission> e = additionalPerms.elements(); - while (e.hasMoreElements()) { - perms.add(e.nextElement()); - } - additionalPerms = null; - } - policy.getPermissions(perms,codesource); - notInit=false; - } - } - - public boolean implies(Permission permission) { - if (notInit) - init(); - return perms.implies(permission); - } - - public Enumeration<Permission> elements() { - if (notInit) - init(); - return perms.elements(); - } - - public String toString() { - if (notInit) - init(); - return perms.toString(); - } -}
--- a/src/share/classes/com/sun/security/auth/PolicyParser.java Tue Aug 27 12:04:32 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,964 +0,0 @@ -/* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.auth; - -import java.io.*; -import java.lang.RuntimePermission; -import java.net.MalformedURLException; -import java.net.SocketPermission; -import java.net.URL; -import java.security.GeneralSecurityException; -import java.text.MessageFormat; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Vector; -import java.util.StringTokenizer; -import sun.security.util.PropertyExpander; - -/** - * The policy for a Java runtime (specifying - * which permissions are available for code from various principals) - * is represented as a separate - * persistent configuration. The configuration may be stored as a - * flat ASCII file, as a serialized binary file of - * the Policy class, or as a database. <p> - * - * <p>The Java runtime creates one global Policy object, which is used to - * represent the static policy configuration file. It is consulted by - * a ProtectionDomain when the protection domain initializes its set of - * permissions. <p> - * - * <p>The Policy <code>init</code> method parses the policy - * configuration file, and then - * populates the Policy object. The Policy object is agnostic in that - * it is not involved in making policy decisions. It is merely the - * Java runtime representation of the persistent policy configuration - * file. <p> - * - * <p>When a protection domain needs to initialize its set of - * permissions, it executes code such as the following - * to ask the global Policy object to populate a - * Permissions object with the appropriate permissions: - * <pre> - * policy = Policy.getPolicy(); - * Permissions perms = policy.getPermissions(MyCodeSource) - * </pre> - * - * <p>The protection domain passes in a CodeSource - * object, which encapsulates its codebase (URL) and public key attributes. - * The Policy object evaluates the global policy in light of who the - * principal is and returns an appropriate Permissions object. - * - * @deprecated As of JDK 1.4, replaced by - * {@link sun.security.provider.PolicyParser}. - * This class is entirely deprecated. - * - * @author Roland Schemers - * - * @since 1.2 - */ -@Deprecated -class PolicyParser { - - private static final java.util.ResourceBundle rb = - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<java.util.ResourceBundle>() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.AuthResources")); - } - }); - - private Vector<GrantEntry> grantEntries; - - // Convenience variables for parsing - private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]"); - private StreamTokenizer st; - private int lookahead; - private int linenum; - private boolean expandProp = false; - private String keyStoreUrlString = null; // unexpanded - private String keyStoreType = null; - - private String expand(String value) - throws PropertyExpander.ExpandException - { - if (expandProp) - return PropertyExpander.expand(value); - else - return value; - } - /** - * Creates a PolicyParser object. - */ - - public PolicyParser() { - grantEntries = new Vector<GrantEntry>(); - } - - - public PolicyParser(boolean expandProp) { - this(); - this.expandProp = expandProp; - } - - /** - * Reads a policy configuration into the Policy object using a - * Reader object. <p> - * - * @param policy the policy Reader object. - * - * @exception ParsingException if the policy configuration contains - * a syntax error. - * - * @exception IOException if an error occurs while reading the policy - * configuration. - */ - - public void read(Reader policy) - throws ParsingException, IOException - { - if (!(policy instanceof BufferedReader)) { - policy = new BufferedReader(policy); - } - - /** - * Configure the stream tokenizer: - * Recognize strings between "..." - * Don't convert words to lowercase - * Recognize both C-style and C++-style comments - * Treat end-of-line as white space, not as a token - */ - st = new StreamTokenizer(policy); - - st.resetSyntax(); - st.wordChars('a', 'z'); - st.wordChars('A', 'Z'); - st.wordChars('.', '.'); - st.wordChars('0', '9'); - st.wordChars('_', '_'); - st.wordChars('$', '$'); - st.wordChars(128 + 32, 255); - st.whitespaceChars(0, ' '); - st.commentChar('/'); - st.quoteChar('\''); - st.quoteChar('"'); - st.lowerCaseMode(false); - st.ordinaryChar('/'); - st.slashSlashComments(true); - st.slashStarComments(true); - - /** - * The main parsing loop. The loop is executed once - * for each entry in the config file. The entries - * are delimited by semicolons. Once we've read in - * the information for an entry, go ahead and try to - * add it to the policy vector. - * - */ - - lookahead = st.nextToken(); - while (lookahead != StreamTokenizer.TT_EOF) { - if (peek("grant")) { - GrantEntry ge = parseGrantEntry(); - // could be null if we couldn't expand a property - if (ge != null) - add(ge); - } else if (peek("keystore") && keyStoreUrlString==null) { - // only one keystore entry per policy file, others will be - // ignored - parseKeyStoreEntry(); - } else { - // error? - } - match(";"); - } - } - - public void add(GrantEntry ge) - { - grantEntries.addElement(ge); - } - - public void replace(GrantEntry origGe, GrantEntry newGe) - { - grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe)); - } - - public boolean remove(GrantEntry ge) - { - return grantEntries.removeElement(ge); - } - - /** - * Returns the (possibly expanded) keystore location, or null if the - * expansion fails. - */ - public String getKeyStoreUrl() { - try { - if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) { - return expand(keyStoreUrlString).replace(File.separatorChar, - '/'); - } - } catch (PropertyExpander.ExpandException peee) { - return null; - } - return null; - } - - public void setKeyStoreUrl(String url) { - keyStoreUrlString = url; - } - - public String getKeyStoreType() { - return keyStoreType; - } - - public void setKeyStoreType(String type) { - keyStoreType = type; - } - - /** - * Enumerate all the entries in the global policy object. - * This method is used by policy admin tools. The tools - * should use the Enumeration methods on the returned object - * to fetch the elements sequentially. - */ - public Enumeration<GrantEntry> grantElements(){ - return grantEntries.elements(); - } - - /** - * write out the policy - */ - - public void write(Writer policy) - { - PrintWriter out = new PrintWriter(new BufferedWriter(policy)); - - Enumeration<GrantEntry> enum_ = grantElements(); - - out.println("/* AUTOMATICALLY GENERATED ON "+ - (new java.util.Date()) + "*/"); - out.println("/* DO NOT EDIT */"); - out.println(); - - // write the (unexpanded) keystore entry as the first entry of the - // policy file - if (keyStoreUrlString != null) { - writeKeyStoreEntry(out); - } - - // write "grant" entries - while (enum_.hasMoreElements()) { - GrantEntry ge = enum_.nextElement(); - ge.write(out); - out.println(); - } - out.flush(); - } - - /** - * parses a keystore entry - */ - private void parseKeyStoreEntry() throws ParsingException, IOException { - match("keystore"); - keyStoreUrlString = match("quoted string"); - - // parse keystore type - if (!peek(",")) { - return; // default type - } - match(","); - - if (peek("\"")) { - keyStoreType = match("quoted string"); - } else { - throw new ParsingException(st.lineno(), - rb.getString("expected.keystore.type")); - } - } - - /** - * writes the (unexpanded) keystore entry - */ - private void writeKeyStoreEntry(PrintWriter out) { - out.print("keystore \""); - out.print(keyStoreUrlString); - out.print('"'); - if (keyStoreType != null && keyStoreType.length() > 0) - out.print(", \"" + keyStoreType + "\""); - out.println(";"); - out.println(); - } - - /** - * parse a Grant entry - */ - private GrantEntry parseGrantEntry() - throws ParsingException, IOException - { - GrantEntry e = new GrantEntry(); - LinkedList<PrincipalEntry> principals = null; - boolean ignoreEntry = false; - - match("grant"); - - while(!peek("{")) { - - if (peekAndMatch("Codebase")) { - e.codeBase = match("quoted string"); - peekAndMatch(","); - } else if (peekAndMatch("SignedBy")) { - e.signedBy = match("quoted string"); - peekAndMatch(","); - } else if (peekAndMatch("Principal")) { - if (principals == null) { - principals = new LinkedList<PrincipalEntry>(); - } - - // check for principalClass wildcard - String principalClass; - if (peek("*")) { - match("*"); - principalClass = PrincipalEntry.WILDCARD_CLASS; - } else { - principalClass = match("principal type"); - } - - // check for principalName wildcard - String principalName; - if (peek("*")) { - match("*"); - principalName = PrincipalEntry.WILDCARD_NAME; - } else { - principalName = match("quoted string"); - } - - // disallow WILDCARD_CLASS && actual name - if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) && - !principalName.equals(PrincipalEntry.WILDCARD_NAME)) { - if (debug != null) - debug.println("disallowing principal that has " + - "WILDCARD class but no WILDCARD name"); - throw new ParsingException - (st.lineno(), - rb.getString("can.not.specify.Principal.with.a." + - "wildcard.class.without.a.wildcard.name")); - } - - try { - principalName = expand(principalName); - principals.add - (new PrincipalEntry(principalClass, principalName)); - } catch (PropertyExpander.ExpandException peee) { - // ignore the entire policy entry - // but continue parsing all the info - // so we can get to the next entry - if (debug != null) - debug.println("principal name expansion failed: " + - principalName); - ignoreEntry = true; - } - peekAndMatch(","); - } else { - throw new - ParsingException(st.lineno(), - rb.getString("expected.codeBase.or.SignedBy")); - } - } - - // disallow non principal-based grant entries - if (principals == null) { - throw new ParsingException - (st.lineno(), - rb.getString("only.Principal.based.grant.entries.permitted")); - } - - e.principals = principals; - match("{"); - - while(!peek("}")) { - if (peek("Permission")) { - try { - PermissionEntry pe = parsePermissionEntry(); - e.add(pe); - } catch (PropertyExpander.ExpandException peee) { - // ignore. The add never happened - skipEntry(); // BugId 4219343 - } - match(";"); - } else { - throw new - ParsingException(st.lineno(), - rb.getString("expected.permission.entry")); - } - } - match("}"); - - try { - if (e.codeBase != null) - e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/'); - e.signedBy = expand(e.signedBy); - } catch (PropertyExpander.ExpandException peee) { - return null; - } - - return (ignoreEntry == true) ? null : e; - } - - /** - * parse a Permission entry - */ - private PermissionEntry parsePermissionEntry() - throws ParsingException, IOException, PropertyExpander.ExpandException - { - PermissionEntry e = new PermissionEntry(); - - // Permission - match("Permission"); - e.permission = match("permission type"); - - if (peek("\"")) { - // Permission name - e.name = expand(match("quoted string")); - } - - if (!peek(",")) { - return e; - } - match(","); - - if (peek("\"")) { - e.action = expand(match("quoted string")); - if (!peek(",")) { - return e; - } - match(","); - } - - if (peekAndMatch("SignedBy")) { - e.signedBy = expand(match("quoted string")); - } - return e; - } - - private boolean peekAndMatch(String expect) - throws ParsingException, IOException - { - if (peek(expect)) { - match(expect); - return true; - } else { - return false; - } - } - - private boolean peek(String expect) { - boolean found = false; - - switch (lookahead) { - - case StreamTokenizer.TT_WORD: - if (expect.equalsIgnoreCase(st.sval)) - found = true; - break; - case ',': - if (expect.equalsIgnoreCase(",")) - found = true; - break; - case '{': - if (expect.equalsIgnoreCase("{")) - found = true; - break; - case '}': - if (expect.equalsIgnoreCase("}")) - found = true; - break; - case '"': - if (expect.equalsIgnoreCase("\"")) - found = true; - break; - case '*': - if (expect.equalsIgnoreCase("*")) - found = true; - break; - default: - - } - return found; - } - - private String match(String expect) - throws ParsingException, IOException - { - String value = null; - - switch (lookahead) { - case StreamTokenizer.TT_NUMBER: - throw new ParsingException(st.lineno(), expect, - rb.getString("number.") + - String.valueOf(st.nval)); - case StreamTokenizer.TT_EOF: - MessageFormat form = new MessageFormat( - rb.getString("expected.expect.read.end.of.file.")); - Object[] source = {expect}; - throw new ParsingException(form.format(source)); - case StreamTokenizer.TT_WORD: - if (expect.equalsIgnoreCase(st.sval)) { - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("permission type")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("principal type")) { - value = st.sval; - lookahead = st.nextToken(); - } else { - throw new ParsingException(st.lineno(), expect, st.sval); - } - break; - case '"': - if (expect.equalsIgnoreCase("quoted string")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("permission type")) { - value = st.sval; - lookahead = st.nextToken(); - } else if (expect.equalsIgnoreCase("principal type")) { - value = st.sval; - lookahead = st.nextToken(); - } else { - throw new ParsingException(st.lineno(), expect, st.sval); - } - break; - case ',': - if (expect.equalsIgnoreCase(",")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, ","); - break; - case '{': - if (expect.equalsIgnoreCase("{")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "{"); - break; - case '}': - if (expect.equalsIgnoreCase("}")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "}"); - break; - case ';': - if (expect.equalsIgnoreCase(";")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, ";"); - break; - case '*': - if (expect.equalsIgnoreCase("*")) - lookahead = st.nextToken(); - else - throw new ParsingException(st.lineno(), expect, "*"); - break; - default: - throw new ParsingException(st.lineno(), expect, - new String(new char[] {(char)lookahead})); - } - return value; - } - - /** - * skip all tokens for this entry leaving the delimiter ";" - * in the stream. - */ - private void skipEntry() - throws ParsingException, IOException - { - while(lookahead != ';') { - switch (lookahead) { - case StreamTokenizer.TT_NUMBER: - throw new ParsingException(st.lineno(), ";", - rb.getString("number.") + - String.valueOf(st.nval)); - case StreamTokenizer.TT_EOF: - throw new ParsingException - (rb.getString("expected.read.end.of.file")); - default: - lookahead = st.nextToken(); - } - } - } - - /** - * Each grant entry in the policy configuration file is - * represented by a - * GrantEntry object. <p> - * - * <p> - * For example, the entry - * <pre> - * grant signedBy "Duke" { - * permission java.io.FilePermission "/tmp", "read,write"; - * }; - * - * </pre> - * is represented internally - * <pre> - * - * pe = new PermissionEntry("java.io.FilePermission", - * "/tmp", "read,write"); - * - * ge = new GrantEntry("Duke", null); - * - * ge.add(pe); - * - * </pre> - * - * @author Roland Schemers - * - * version 1.19, 05/21/98 - */ - - static class GrantEntry { - - public String signedBy; - public String codeBase; - public LinkedList<PrincipalEntry> principals; - public Vector<PermissionEntry> permissionEntries; - - public GrantEntry() { - permissionEntries = new Vector<PermissionEntry>(); - } - - public GrantEntry(String signedBy, String codeBase) { - this.codeBase = codeBase; - this.signedBy = signedBy; - permissionEntries = new Vector<PermissionEntry>(); - } - - public void add(PermissionEntry pe) - { - permissionEntries.addElement(pe); - } - - public boolean remove(PermissionEntry pe) - { - return permissionEntries.removeElement(pe); - } - - public boolean contains(PermissionEntry pe) - { - return permissionEntries.contains(pe); - } - - /** - * Enumerate all the permission entries in this GrantEntry. - */ - public Enumeration<PermissionEntry> permissionElements(){ - return permissionEntries.elements(); - } - - - public void write(PrintWriter out) { - out.print("grant"); - if (signedBy != null) { - out.print(" signedBy \""); - out.print(signedBy); - out.print('"'); - if (codeBase != null) - out.print(", "); - } - if (codeBase != null) { - out.print(" codeBase \""); - out.print(codeBase); - out.print('"'); - if (principals != null && principals.size() > 0) - out.print(",\n"); - } - if (principals != null && principals.size() > 0) { - ListIterator<PrincipalEntry> pli = principals.listIterator(); - while (pli.hasNext()) { - out.print("\tPrincipal "); - PrincipalEntry pe = pli.next(); - out.print(pe.principalClass + - " \"" + pe.principalName + "\""); - if (pli.hasNext()) - out.print(",\n"); - } - } - out.println(" {"); - Enumeration<PermissionEntry> enum_ = permissionEntries.elements(); - while (enum_.hasMoreElements()) { - PermissionEntry pe = enum_.nextElement(); - out.write(" "); - pe.write(out); - } - out.println("};"); - } - - } - - /** - * Principal info (class and name) in a grant entry - */ - static class PrincipalEntry { - - static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS"; - static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME"; - - String principalClass; - String principalName; - - /** - * A PrincipalEntry consists of the <code>Principal</code> - * class and <code>Principal</code> name. - * - * <p> - * - * @param principalClass the <code>Principal</code> class. <p> - * - * @param principalName the <code>Principal</code> name. <p> - */ - public PrincipalEntry(String principalClass, String principalName) { - if (principalClass == null || principalName == null) - throw new NullPointerException - ("null principalClass or principalName"); - this.principalClass = principalClass; - this.principalName = principalName; - } - - /** - * Test for equality between the specified object and this object. - * Two PrincipalEntries are equal if their PrincipalClass and - * PrincipalName values are equal. - * - * <p> - * - * @param obj the object to test for equality with this object. - * - * @return true if the objects are equal, false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) - return true; - - if (!(obj instanceof PrincipalEntry)) - return false; - - PrincipalEntry that = (PrincipalEntry)obj; - if (this.principalClass.equals(that.principalClass) && - this.principalName.equals(that.principalName)) { - return true; - } - - return false; - } - - /** - * Return a hashcode for this <code>PrincipalEntry</code>. - * - * <p> - * - * @return a hashcode for this <code>PrincipalEntry</code>. - */ - public int hashCode() { - return principalClass.hashCode(); - } - } - - /** - * Each permission entry in the policy configuration file is - * represented by a - * PermissionEntry object. <p> - * - * <p> - * For example, the entry - * <pre> - * permission java.io.FilePermission "/tmp", "read,write"; - * </pre> - * is represented internally - * <pre> - * - * pe = new PermissionEntry("java.io.FilePermission", - * "/tmp", "read,write"); - * </pre> - * - * @author Roland Schemers - * - * version 1.19, 05/21/98 - */ - - static class PermissionEntry { - - public String permission; - public String name; - public String action; - public String signedBy; - - public PermissionEntry() { - } - - public PermissionEntry(String permission, - String name, - String action) { - this.permission = permission; - this.name = name; - this.action = action; - } - - /** - * Calculates a hash code value for the object. Objects - * which are equal will also have the same hashcode. - */ - public int hashCode() { - int retval = permission.hashCode(); - if (name != null) retval ^= name.hashCode(); - if (action != null) retval ^= action.hashCode(); - return retval; - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (! (obj instanceof PermissionEntry)) - return false; - - PermissionEntry that = (PermissionEntry) obj; - - if (this.permission == null) { - if (that.permission != null) return false; - } else { - if (!this.permission.equals(that.permission)) return false; - } - - if (this.name == null) { - if (that.name != null) return false; - } else { - if (!this.name.equals(that.name)) return false; - } - - if (this.action == null) { - if (that.action != null) return false; - } else { - if (!this.action.equals(that.action)) return false; - } - - if (this.signedBy == null) { - if (that.signedBy != null) return false; - } else { - if (!this.signedBy.equals(that.signedBy)) return false; - } - - // everything matched -- the 2 objects are equal - return true; - } - - public void write(PrintWriter out) { - out.print("permission "); - out.print(permission); - if (name != null) { - out.print(" \""); - - // have to add escape chars for quotes - if (name.indexOf("\"") != -1) { - int numQuotes = 0; - char[] chars = name.toCharArray(); - - // count the number of quote chars - for (int i = 0; i < chars.length; i++) { - if (chars[i] == '"') - numQuotes++; - } - - // now, add an escape char before each quote - char[] newChars = new char[chars.length + numQuotes]; - for (int i = 0, j = 0; i < chars.length; i++) { - if (chars[i] != '"') { - newChars[j++] = chars[i]; - } else { - newChars[j++] = '\\'; - newChars[j++] = chars[i]; - } - } - name = new String(newChars); - } - out.print(name); - out.print('"'); - } - if (action != null) { - out.print(", \""); - out.print(action); - out.print('"'); - } - if (signedBy != null) { - out.print(", signedBy \""); - out.print(signedBy); - out.print('"'); - } - out.println(";"); - } - } - - static class ParsingException extends GeneralSecurityException { - - private static final long serialVersionUID = 8240970523155877400L; - - /** - * Constructs a ParsingException with the specified - * detail message. A detail message is a String that describes - * this particular exception, which may, for example, specify which - * algorithm is not available. - * - * @param msg the detail message. - */ - public ParsingException(String msg) { - super(msg); - } - - public ParsingException(int line, String msg) { - super(rb.getString("line.") + line + rb.getString("COLON") + msg); - } - - public ParsingException(int line, String expect, String actual) { - super(rb.getString("line.") + line + rb.getString(".expected.") + - expect + rb.getString(".found.") + actual + - rb.getString("QUOTE")); - } - } - - public static void main(String arg[]) throws Exception { - PolicyParser pp = new PolicyParser(true); - pp.read(new FileReader(arg[0])); - FileWriter fr = new FileWriter(arg[1]); - pp.write(fr); - fr.close(); - } -}
--- a/src/share/classes/com/sun/security/auth/SubjectCodeSource.java Tue Aug 27 12:04:32 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,398 +0,0 @@ -/* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.security.auth; - -import java.net.URL; -import java.util.*; -import java.security.CodeSource; -import java.security.Principal; -import java.security.cert.Certificate; -import java.lang.reflect.Constructor; - -import javax.security.auth.Subject; -import sun.security.provider.PolicyParser.PrincipalEntry; - -/** - * <p> This <code>SubjectCodeSource</code> class contains - * a <code>URL</code>, signer certificates, and either a <code>Subject</code> - * (that represents the <code>Subject</code> in the current - * <code>AccessControlContext</code>), - * or a linked list of Principals/PrincipalComparators - * (that represent a "subject" in a <code>Policy</code>). - * - */ -class SubjectCodeSource extends CodeSource implements java.io.Serializable { - - private static final long serialVersionUID = 6039418085604715275L; - - private static final java.util.ResourceBundle rb = - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<java.util.ResourceBundle>() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.AuthResources")); - } - }); - - private Subject subject; - private LinkedList<PrincipalEntry> principals; - private static final Class[] PARAMS = { String.class }; - private static final sun.security.util.Debug debug = - sun.security.util.Debug.getInstance("auth", "\t[Auth Access]"); - private ClassLoader sysClassLoader; - - /** - * Creates a new <code>SubjectCodeSource</code> - * with the given <code>Subject</code>, principals, <code>URL</code>, - * and signers (Certificates). The <code>Subject</code> - * represents the <code>Subject</code> associated with the current - * <code>AccessControlContext</code>. - * The Principals are given as a <code>LinkedList</code> - * of <code>PolicyParser.PrincipalEntry</code> objects. - * Typically either a <code>Subject</code> will be provided, - * or a list of <code>principals</code> will be provided - * (not both). - * - * <p> - * - * @param subject the <code>Subject</code> associated with this - * <code>SubjectCodeSource</code> <p> - * - * @param url the <code>URL</code> associated with this - * <code>SubjectCodeSource</code> <p> - * - * @param certs the signers associated with this - * <code>SubjectCodeSource</code> <p> - */ - SubjectCodeSource(Subject subject, - LinkedList<PrincipalEntry> principals, - URL url, Certificate[] certs) { - - super(url, certs); - this.subject = subject; - this.principals = (principals == null ? - new LinkedList<PrincipalEntry>() : - new LinkedList<PrincipalEntry>(principals)); - sysClassLoader = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - return ClassLoader.getSystemClassLoader(); - } - }); - } - - /** - * Get the Principals associated with this <code>SubjectCodeSource</code>. - * The Principals are retrieved as a <code>LinkedList</code> - * of <code>PolicyParser.PrincipalEntry</code> objects. - * - * <p> - * - * @return the Principals associated with this - * <code>SubjectCodeSource</code> as a <code>LinkedList</code> - * of <code>PolicyParser.PrincipalEntry</code> objects. - */ - LinkedList<PrincipalEntry> getPrincipals() { - return principals; - } - - /** - * Get the <code>Subject</code> associated with this - * <code>SubjectCodeSource</code>. The <code>Subject</code> - * represents the <code>Subject</code> associated with the - * current <code>AccessControlContext</code>. - * - * <p> - * - * @return the <code>Subject</code> associated with this - * <code>SubjectCodeSource</code>. - */ - Subject getSubject() { - return subject; - } - - /** - * Returns true if this <code>SubjectCodeSource</code> object "implies" - * the specified <code>CodeSource</code>. - * More specifically, this method makes the following checks. - * If any fail, it returns false. If they all succeed, it returns true. - * - * <p> - * <ol> - * <li> The provided codesource must not be <code>null</code>. - * <li> codesource must be an instance of <code>SubjectCodeSource</code>. - * <li> super.implies(codesource) must return true. - * <li> for each principal in this codesource's principal list: - * <ol> - * <li> if the principal is an instanceof - * <code>PrincipalComparator</code>, then the principal must - * imply the provided codesource's <code>Subject</code>. - * <li> if the principal is not an instanceof - * <code>PrincipalComparator</code>, then the provided - * codesource's <code>Subject</code> must have an - * associated <code>Principal</code>, <i>P</i>, where - * P.getClass().getName equals principal.principalClass, - * and P.getName() equals principal.principalName. - * </ol> - * </ol> - * - * <p> - * - * @param codesource the <code>CodeSource</code> to compare against. - * - * @return true if this <code>SubjectCodeSource</code> implies the - * the specified <code>CodeSource</code>. - */ - public boolean implies(CodeSource codesource) { - - LinkedList<PrincipalEntry> subjectList = null; - - if (codesource == null || - !(codesource instanceof SubjectCodeSource) || - !(super.implies(codesource))) { - - if (debug != null) - debug.println("\tSubjectCodeSource.implies: FAILURE 1"); - return false; - } - - SubjectCodeSource that = (SubjectCodeSource)codesource; - - // if the principal list in the policy "implies" - // the Subject associated with the current AccessControlContext, - // then return true - - if (this.principals == null) { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: PASS 1"); - return true; - } - - if (that.getSubject() == null || - that.getSubject().getPrincipals().size() == 0) { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: FAILURE 2"); - return false; - } - - ListIterator<PrincipalEntry> li = this.principals.listIterator(0); - while (li.hasNext()) { - PrincipalEntry pppe = li.next(); - try { - - // handle PrincipalComparators - - Class<?> principalComparator = Class.forName( - pppe.getPrincipalClass(), true, sysClassLoader); - Constructor<?> c = principalComparator.getConstructor(PARAMS); - PrincipalComparator pc = - (PrincipalComparator)c.newInstance - (new Object[] { pppe.getPrincipalName() }); - - if (!pc.implies(that.getSubject())) { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: FAILURE 3"); - return false; - } else { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: PASS 2"); - return true; - } - } catch (Exception e) { - - // no PrincipalComparator, simply compare Principals - - if (subjectList == null) { - - if (that.getSubject() == null) { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: " + - "FAILURE 4"); - return false; - } - Iterator<Principal> i = - that.getSubject().getPrincipals().iterator(); - - subjectList = new LinkedList<PrincipalEntry>(); - while (i.hasNext()) { - Principal p = i.next(); - PrincipalEntry spppe = new PrincipalEntry - (p.getClass().getName(), p.getName()); - subjectList.add(spppe); - } - } - - if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) { - if (debug != null) - debug.println("\tSubjectCodeSource.implies: FAILURE 5"); - return false; - } - } - } - - if (debug != null) - debug.println("\tSubjectCodeSource.implies: PASS 3"); - return true; - } - - /** - * This method returns, true, if the provided <i>subjectList</i> - * "contains" the <code>Principal</code> specified - * in the provided <i>pppe</i> argument. - * - * Note that the provided <i>pppe</i> argument may have - * wildcards (*) for the <code>Principal</code> class and name, - * which need to be considered. - * - * <p> - * - * @param subjectList a list of PolicyParser.PrincipalEntry objects - * that correspond to all the Principals in the Subject currently - * on this thread's AccessControlContext. <p> - * - * @param pppe the Principals specified in a grant entry. - * - * @return true if the provided <i>subjectList</i> "contains" - * the <code>Principal</code> specified in the provided - * <i>pppe</i> argument. - */ - private boolean subjectListImpliesPrincipalEntry( - LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) { - - ListIterator<PrincipalEntry> li = subjectList.listIterator(0); - while (li.hasNext()) { - PrincipalEntry listPppe = li.next(); - - if (pppe.getPrincipalClass().equals - (PrincipalEntry.WILDCARD_CLASS) || - pppe.getPrincipalClass().equals(listPppe.getPrincipalClass())) - { - if (pppe.getPrincipalName().equals - (PrincipalEntry.WILDCARD_NAME) || - pppe.getPrincipalName().equals(listPppe.getPrincipalName())) - return true; - } - } - return false; - } - - /** - * Tests for equality between the specified object and this - * object. Two <code>SubjectCodeSource</code> objects are considered equal - * if their locations are of identical value, if the two sets of - * Certificates are of identical values, and if the - * Subjects are equal, and if the PolicyParser.PrincipalEntry values - * are of identical values. It is not required that - * the Certificates or PolicyParser.PrincipalEntry values - * be in the same order. - * - * <p> - * - * @param obj the object to test for equality with this object. - * - * @return true if the objects are considered equal, false otherwise. - */ - public boolean equals(Object obj) { - - if (obj == this) - return true; - - if (super.equals(obj) == false) - return false; - - if (!(obj instanceof SubjectCodeSource)) - return false; - - SubjectCodeSource that = (SubjectCodeSource)obj; - - // the principal lists must match - try { - if (this.getSubject() != that.getSubject()) - return false; - } catch (SecurityException se) { - return false; - } - - if ((this.principals == null && that.principals != null) || - (this.principals != null && that.principals == null)) - return false; - - if (this.principals != null && that.principals != null) { - if (!this.principals.containsAll(that.principals) || - !that.principals.containsAll(this.principals)) - - return false; - } - - return true; - } - - /** - * Return a hashcode for this <code>SubjectCodeSource</code>. - * - * <p> - * - * @return a hashcode for this <code>SubjectCodeSource</code>. - */ - public int hashCode() { - return super.hashCode(); - } - - /** - * Return a String representation of this <code>SubjectCodeSource</code>. - * - * <p> - * - * @return a String representation of this <code>SubjectCodeSource</code>. - */ - public String toString() { - String returnMe = super.toString(); - if (getSubject() != null) { - if (debug != null) { - final Subject finalSubject = getSubject(); - returnMe = returnMe + "\n" + - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<String>() { - public String run() { - return finalSubject.toString(); - } - }); - } else { - returnMe = returnMe + "\n" + getSubject().toString(); - } - } - if (principals != null) { - ListIterator<PrincipalEntry> li = principals.listIterator(); - while (li.hasNext()) { - PrincipalEntry pppe = li.next(); - returnMe = returnMe + rb.getString("NEWLINE") + - pppe.getPrincipalClass() + " " + - pppe.getPrincipalName(); - } - } - return returnMe; - } -}
--- a/src/share/classes/com/sun/tools/attach/VirtualMachine.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/tools/attach/VirtualMachine.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -59,7 +59,7 @@ * {@link java.lang.instrument} for a detailed description on how these agents * are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and * {@link #loadAgentPath loadAgentPath} methods are used to load agents that - * are deployed in a dynamic library and make use of the <a + * are deployed either in a dynamic library or statically linked into the VM and make use of the <a * href="../../../../../../../../technotes/guides/jvmti/index.html">JVM Tools * Interface</a>. </p> * @@ -298,25 +298,29 @@ * <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM * TI</a> client is called an <i>agent</i>. It is developed in a native language. * A JVM TI agent is deployed in a platform specific manner but it is typically the - * platform equivalent of a dynamic library. This method causes the given agent - * library to be loaded into the target VM (if not already loaded). + * platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM. + * This method causes the given agent library to be loaded into the target + * VM (if not already loaded or if not statically linked into the VM). * It then causes the target VM to invoke the <code>Agent_OnAttach</code> function + * or, for a statically linked agent named 'L', the <code>Agent_OnAttach_L</code> function * as specified in the * <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools - * Interface</a> specification. Note that the <code>Agent_OnAttach</code> + * Interface</a> specification. Note that the <code>Agent_OnAttach[_L]</code> * function is invoked even if the agent library was loaded prior to invoking * this method. * * <p> The agent library provided is the name of the agent library. It is interpreted * in the target virtual machine in an implementation-dependent manner. Typically an * implementation will expand the library name into an operating system specific file - * name. For example, on UNIX systems, the name <tt>foo</tt> might be expanded to - * <tt>libfoo.so</tt>, and located using the search path specified by the - * <tt>LD_LIBRARY_PATH</tt> environment variable.</p> + * name. For example, on UNIX systems, the name <tt>L</tt> might be expanded to + * <tt>libL.so</tt>, and located using the search path specified by the + * <tt>LD_LIBRARY_PATH</tt> environment variable. If the agent named 'L' is + * statically linked into the VM then the VM must export a function named + * <code>Agent_OnAttach_L</code>.</p> * - * <p> If the <code>Agent_OnAttach</code> function in the agent library returns + * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns * an error then an {@link com.sun.tools.attach.AgentInitializationException} is - * thrown. The return value from the <code>Agent_OnAttach</code> can then be + * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be * obtained by invoking the {@link * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue} * method on the exception. </p> @@ -325,15 +329,16 @@ * The name of the agent library. * * @param options - * The options to provide to the <code>Agent_OnAttach</code> + * The options to provide to the <code>Agent_OnAttach[_L]</code> * function (can be <code>null</code>). * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the <code>Agent_OnAttach</code> function returns an error + * If the <code>Agent_OnAttach[_L]</code> function returns an error. * * @throws IOException * If an I/O error occurs @@ -359,11 +364,12 @@ * The name of the agent library. * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the <code>Agent_OnAttach</code> function returns an error + * If the <code>Agent_OnAttach[_L]</code> function returns an error. * * @throws IOException * If an I/O error occurs @@ -383,12 +389,23 @@ * <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM * TI</a> client is called an <i>agent</i>. It is developed in a native language. * A JVM TI agent is deployed in a platform specific manner but it is typically the - * platform equivalent of a dynamic library. This method causes the given agent - * library to be loaded into the target VM (if not already loaded). - * It then causes the target VM to invoke the <code>Agent_OnAttach</code> function - * as specified in the + * platform equivalent of a dynamic library. Alternatively, the native + * library specified by the agentPath parameter may be statically + * linked with the VM. The parsing of the agentPath parameter into + * a statically linked library name is done in a platform + * specific manner in the VM. For example, in UNIX, an agentPath parameter + * of <code>/a/b/libL.so</code> would name a library 'L'. + * + * See the JVM TI Specification for more details. + * + * This method causes the given agent library to be loaded into the target + * VM (if not already loaded or if not statically linked into the VM). + * It then causes the target VM to invoke the <code>Agent_OnAttach</code> + * function or, for a statically linked agent named 'L', the + * <code>Agent_OnAttach_L</code> function as specified in the * <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools - * Interface</a> specification. Note that the <code>Agent_OnAttach</code> + * Interface</a> specification. + * Note that the <code>Agent_OnAttach[_L]</code> * function is invoked even if the agent library was loaded prior to invoking * this method. * @@ -396,9 +413,9 @@ * agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name * is not expanded in the target virtual machine. </p> * - * <p> If the <code>Agent_OnAttach</code> function in the agent library returns + * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns * an error then an {@link com.sun.tools.attach.AgentInitializationException} is - * thrown. The return value from the <code>Agent_OnAttach</code> can then be + * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be * obtained by invoking the {@link * com.sun.tools.attach.AgentInitializationException#returnValue() returnValue} * method on the exception. </p> @@ -407,15 +424,16 @@ * The full path of the agent library. * * @param options - * The options to provide to the <code>Agent_OnAttach</code> + * The options to provide to the <code>Agent_OnAttach[_L]</code> * function (can be <code>null</code>). * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the <code>Agent_OnAttach</code> function returns an error + * If the <code>Agent_OnAttach[_L]</code> function returns an error. * * @throws IOException * If an I/O error occurs @@ -441,11 +459,12 @@ * The full path to the agent library. * * @throws AgentLoadException - * If the agent library does not exist, or cannot be loaded for - * another reason. + * If the agent library does not exist, the agent library is not + * statically linked with the VM, or the agent library cannot be + * loaded for another reason. * * @throws AgentInitializationException - * If the <code>Agent_OnAttach</code> function returns an error + * If the <code>Agent_OnAttach[_L]</code> function returns an error. * * @throws IOException * If an I/O error occurs
--- a/src/share/classes/com/sun/tools/hat/resources/hat.js Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/com/sun/tools/hat/resources/hat.js Tue Aug 27 12:27:31 2013 -0400 @@ -1144,7 +1144,7 @@ } else { for (var index in array) { var it = array[index]; - if (func(it, index, array)) { + if (func(it, String(index), array)) { return true; } } @@ -1244,7 +1244,7 @@ var result = new Array(); for (var index in array) { var it = array[index]; - if (func(it, index, array, result)) { + if (func(it, String(index), array, result)) { result[result.length] = it; } } @@ -1317,7 +1317,7 @@ var result = new Array(); for (var index in array) { var it = array[index]; - result[result.length] = func(it, index, array, result); + result[result.length] = func(it, String(index), array, result); } return result; }
--- a/src/share/classes/java/awt/KeyboardFocusManager.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/awt/KeyboardFocusManager.java Tue Aug 27 12:27:31 2013 -0400 @@ -2426,7 +2426,8 @@ focusLog.finest("Request {0}", String.valueOf(hwFocusRequest)); } if (hwFocusRequest == null && - heavyweight == nativeFocusOwner) + heavyweight == nativeFocusOwner && + heavyweight.getContainingWindow() == nativeFocusedWindow) { if (descendant == currentFocusOwner) { // Redundant request.
--- a/src/share/classes/java/awt/Window.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/awt/Window.java Tue Aug 27 12:27:31 2013 -0400 @@ -62,18 +62,18 @@ import sun.util.logging.PlatformLogger; /** - * A <code>Window</code> object is a top-level window with no borders and no + * A {@code Window} object is a top-level window with no borders and no * menubar. - * The default layout for a window is <code>BorderLayout</code>. + * The default layout for a window is {@code BorderLayout}. * <p> * A window must have either a frame, dialog, or another window defined as its * owner when it's constructed. * <p> - * In a multi-screen environment, you can create a <code>Window</code> - * on a different screen device by constructing the <code>Window</code> + * In a multi-screen environment, you can create a {@code Window} + * on a different screen device by constructing the {@code Window} * with {@link #Window(Window, GraphicsConfiguration)}. The - * <code>GraphicsConfiguration</code> object is one of the - * <code>GraphicsConfiguration</code> objects of the target screen device. + * {@code GraphicsConfiguration} object is one of the + * {@code GraphicsConfiguration} objects of the target screen device. * <p> * In a virtual device multi-screen environment in which the desktop * area could span multiple physical screen devices, the bounds of all @@ -87,21 +87,21 @@ * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)." * ALIGN=center HSPACE=10 VSPACE=7> * <p> - * In such an environment, when calling <code>setLocation</code>, + * In such an environment, when calling {@code setLocation}, * you must pass a virtual coordinate to this method. Similarly, - * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns - * virtual device coordinates. Call the <code>getBounds</code> method - * of a <code>GraphicsConfiguration</code> to find its origin in the virtual + * calling {@code getLocationOnScreen} on a {@code Window} returns + * virtual device coordinates. Call the {@code getBounds} method + * of a {@code GraphicsConfiguration} to find its origin in the virtual * coordinate system. * <p> - * The following code sets the location of a <code>Window</code> + * The following code sets the location of a {@code Window} * at (10, 10) relative to the origin of the physical screen - * of the corresponding <code>GraphicsConfiguration</code>. If the - * bounds of the <code>GraphicsConfiguration</code> is not taken - * into account, the <code>Window</code> location would be set + * of the corresponding {@code GraphicsConfiguration}. If the + * bounds of the {@code GraphicsConfiguration} is not taken + * into account, the {@code Window} location would be set * at (10, 10) relative to the virtual-coordinate system and would appear * on the primary physical screen, which might be different from the - * physical screen of the specified <code>GraphicsConfiguration</code>. + * physical screen of the specified {@code GraphicsConfiguration}. * * <pre> * Window w = new Window(Window owner, GraphicsConfiguration gc); @@ -111,19 +111,19 @@ * * <p> * Note: the location and size of top-level windows (including - * <code>Window</code>s, <code>Frame</code>s, and <code>Dialog</code>s) + * {@code Window}s, {@code Frame}s, and {@code Dialog}s) * are under the control of the desktop's window management system. - * Calls to <code>setLocation</code>, <code>setSize</code>, and - * <code>setBounds</code> are requests (not directives) which are + * Calls to {@code setLocation}, {@code setSize}, and + * {@code setBounds} are requests (not directives) which are * forwarded to the window management system. Every effort will be * made to honor such requests. However, in some cases the window * management system may ignore such requests, or modify the requested - * geometry in order to place and size the <code>Window</code> in a way + * geometry in order to place and size the {@code Window} in a way * that more closely matches the desktop settings. * <p> * Due to the asynchronous nature of native event handling, the results - * returned by <code>getBounds</code>, <code>getLocation</code>, - * <code>getLocationOnScreen</code>, and <code>getSize</code> might not + * returned by {@code getBounds}, {@code getLocation}, + * {@code getLocationOnScreen}, and {@code getSize} might not * reflect the actual geometry of the Window on screen until the last * request has been processed. During the processing of subsequent * requests these values might change accordingly while the window @@ -340,7 +340,7 @@ */ transient boolean isInShow = false; - /* + /** * The opacity level of the window * * @serial @@ -350,7 +350,7 @@ */ private float opacity = 1.0f; - /* + /** * The shape assigned to this window. This field is set to {@code null} if * no shape is set (rectangular window). * @@ -415,21 +415,21 @@ /** * Constructs a new, initially invisible window in default size with the - * specified <code>GraphicsConfiguration</code>. + * specified {@code GraphicsConfiguration}. * <p> * If there is a security manager, this method first calls - * the security manager's <code>checkTopLevelWindow</code> - * method with <code>this</code> + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param gc the <code>GraphicsConfiguration</code> of the target screen - * device. If <code>gc</code> is <code>null</code>, the system default - * <code>GraphicsConfiguration</code> is assumed - * @exception IllegalArgumentException if <code>gc</code> + * @param gc the {@code GraphicsConfiguration} of the target screen + * device. If {@code gc} is {@code null}, the system default + * {@code GraphicsConfiguration} is assumed + * @exception IllegalArgumentException if {@code gc} * is not from a screen device * @exception HeadlessException when - * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code> + * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -513,20 +513,20 @@ * Constructs a new, initially invisible window in the default size. * * <p>First, if there is a security manager, its - * <code>checkTopLevelWindow</code> - * method is called with <code>this</code> + * {@code checkTopLevelWindow} + * method is called with {@code this} * as its argument * to see if it's ok to display the window without a warning banner. - * If the default implementation of <code>checkTopLevelWindow</code> + * If the default implementation of {@code checkTopLevelWindow} * is used (that is, that method is not overriden), then this results in - * a call to the security manager's <code>checkPermission</code> method - * with an <code>AWTPermission("showWindowWithoutWarningBanner")</code> + * a call to the security manager's {@code checkPermission} method + * with an {@code AWTPermission("showWindowWithoutWarningBanner")} * permission. It that method raises a SecurityException, - * <code>checkTopLevelWindow</code> returns false, otherwise it + * {@code checkTopLevelWindow} returns false, otherwise it * returns true. If it returns false, a warning banner is created. * * @exception HeadlessException when - * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code> + * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -538,21 +538,21 @@ /** * Constructs a new, initially invisible window with the specified - * <code>Frame</code> as its owner. The window will not be focusable + * {@code Frame} as its owner. The window will not be focusable * unless its owner is showing on the screen. * <p> * If there is a security manager, this method first calls - * the security manager's <code>checkTopLevelWindow</code> - * method with <code>this</code> + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the <code>Frame</code> to act as owner or <code>null</code> + * @param owner the {@code Frame} to act as owner or {@code null} * if this window has no owner - * @exception IllegalArgumentException if the <code>owner</code>'s - * <code>GraphicsConfiguration</code> is not from a screen device + * @exception IllegalArgumentException if the {@code owner}'s + * {@code GraphicsConfiguration} is not from a screen device * @exception HeadlessException when - * <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code> + * {@code GraphicsEnvironment.isHeadless} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -566,23 +566,23 @@ /** * Constructs a new, initially invisible window with the specified - * <code>Window</code> as its owner. This window will not be focusable - * unless its nearest owning <code>Frame</code> or <code>Dialog</code> + * {@code Window} as its owner. This window will not be focusable + * unless its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. * <p> * If there is a security manager, this method first calls - * the security manager's <code>checkTopLevelWindow</code> - * method with <code>this</code> + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the <code>Window</code> to act as owner or - * <code>null</code> if this window has no owner - * @exception IllegalArgumentException if the <code>owner</code>'s - * <code>GraphicsConfiguration</code> is not from a screen device + * @param owner the {@code Window} to act as owner or + * {@code null} if this window has no owner + * @exception IllegalArgumentException if the {@code owner}'s + * {@code GraphicsConfiguration} is not from a screen device * @exception HeadlessException when - * <code>GraphicsEnvironment.isHeadless()</code> returns - * <code>true</code> + * {@code GraphicsEnvironment.isHeadless()} returns + * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -598,27 +598,27 @@ /** * Constructs a new, initially invisible window with the specified owner - * <code>Window</code> and a <code>GraphicsConfiguration</code> + * {@code Window} and a {@code GraphicsConfiguration} * of a screen device. The Window will not be focusable unless - * its nearest owning <code>Frame</code> or <code>Dialog</code> + * its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. * <p> * If there is a security manager, this method first calls - * the security manager's <code>checkTopLevelWindow</code> - * method with <code>this</code> + * the security manager's {@code checkTopLevelWindow} + * method with {@code this} * as its argument to determine whether or not the window * must be displayed with a warning banner. * - * @param owner the window to act as owner or <code>null</code> + * @param owner the window to act as owner or {@code null} * if this window has no owner - * @param gc the <code>GraphicsConfiguration</code> of the target - * screen device; if <code>gc</code> is <code>null</code>, - * the system default <code>GraphicsConfiguration</code> is assumed - * @exception IllegalArgumentException if <code>gc</code> + * @param gc the {@code GraphicsConfiguration} of the target + * screen device; if {@code gc} is {@code null}, + * the system default {@code GraphicsConfiguration} is assumed + * @exception IllegalArgumentException if {@code gc} * is not from a screen device * @exception HeadlessException when - * <code>GraphicsEnvironment.isHeadless()</code> returns - * <code>true</code> + * {@code GraphicsEnvironment.isHeadless()} returns + * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless * @see java.lang.SecurityManager#checkTopLevelWindow @@ -936,7 +936,7 @@ /** * @deprecated As of JDK version 1.1, - * replaced by <code>setBounds(int, int, int, int)</code>. + * replaced by {@code setBounds(int, int, int, int)}. */ @Deprecated public void reshape(int x, int y, int width, int height) { @@ -1122,16 +1122,16 @@ /** * Releases all of the native screen resources used by this - * <code>Window</code>, its subcomponents, and all of its owned - * children. That is, the resources for these <code>Component</code>s + * {@code Window}, its subcomponents, and all of its owned + * children. That is, the resources for these {@code Component}s * will be destroyed, any memory they consume will be returned to the * OS, and they will be marked as undisplayable. * <p> - * The <code>Window</code> and its subcomponents can be made displayable + * The {@code Window} and its subcomponents can be made displayable * again by rebuilding the native resources with a subsequent call to - * <code>pack</code> or <code>show</code>. The states of the recreated - * <code>Window</code> and its subcomponents will be identical to the - * states of these objects at the point where the <code>Window</code> + * {@code pack} or {@code show}. The states of the recreated + * {@code Window} and its subcomponents will be identical to the + * states of these objects at the point where the {@code Window} * was disposed (not accounting for additional modifications between * those actions). * <p> @@ -1363,14 +1363,14 @@ * If this window is insecure, the warning string is displayed * somewhere in the visible area of the window. A window is * insecure if there is a security manager, and the security - * manager's <code>checkTopLevelWindow</code> method returns - * <code>false</code> when this window is passed to it as an + * manager's {@code checkTopLevelWindow} method returns + * {@code false} when this window is passed to it as an * argument. * <p> - * If the window is secure, then <code>getWarningString</code> - * returns <code>null</code>. If the window is insecure, this + * If the window is secure, then {@code getWarningString} + * returns {@code null}. If the window is insecure, this * method checks for the system property - * <code>awt.appletWarning</code> + * {@code awt.appletWarning} * and returns the string value of that property. * @return the warning string for this window. * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) @@ -1395,7 +1395,7 @@ } /** - * Gets the <code>Locale</code> object that is associated + * Gets the {@code Locale} object that is associated * with this window, if the locale has been set. * If no locale has been set, then the default locale * is returned. @@ -1432,7 +1432,7 @@ * implementation and/or the native system do not support * changing the mouse cursor shape. * @param cursor One of the constants defined - * by the <code>Cursor</code> class. If this parameter is null + * by the {@code Cursor} class. If this parameter is null * then the cursor for this window will be set to the type * Cursor.DEFAULT_CURSOR. * @see Component#getCursor @@ -1579,7 +1579,7 @@ * <b>Warning:</b> this method may return system created windows, such * as a print dialog. Applications should not assume the existence of * these dialogs, nor should an application assume anything about these - * dialogs such as component positions, <code>LayoutManager</code>s + * dialogs such as component positions, {@code LayoutManager}s * or serialization. * * @see Frame#getFrames @@ -1601,7 +1601,7 @@ * <b>Warning:</b> this method may return system created windows, such * as a print dialog. Applications should not assume the existence of * these dialogs, nor should an application assume anything about these - * dialogs such as component positions, <code>LayoutManager</code>s + * dialogs such as component positions, {@code LayoutManager}s * or serialization. * * @see Frame#getFrames @@ -1646,17 +1646,17 @@ * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for * possible modal exclusion types. * <p> - * If the given type is not supported, <code>NO_EXCLUDE</code> is used. + * If the given type is not supported, {@code NO_EXCLUDE} is used. * <p> * Note: changing the modal exclusion type for a visible window may have no * effect until it is hidden and then shown again. * - * @param exclusionType the modal exclusion type for this window; a <code>null</code> + * @param exclusionType the modal exclusion type for this window; a {@code null} * value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE * NO_EXCLUDE} * @throws SecurityException if the calling thread does not have permission * to set the modal exclusion property to the window with the given - * <code>exclusionType</code> + * {@code exclusionType} * @see java.awt.Dialog.ModalExclusionType * @see java.awt.Window#getModalExclusionType * @see java.awt.Toolkit#isModalExclusionTypeSupported @@ -1762,7 +1762,7 @@ /** * Adds the specified window state listener to receive window - * events from this window. If <code>l</code> is <code>null</code>, + * events from this window. If {@code l} is {@code null}, * no exception is thrown and no action is performed. * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" * >AWT Threading Issues</a> for details on AWT's threading model. @@ -1821,7 +1821,7 @@ /** * Removes the specified window state listener so that it no * longer receives window events from this window. If - * <code>l</code> is <code>null</code>, no exception is thrown and + * {@code l} is {@code null}, no exception is thrown and * no action is performed. * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" * >AWT Threading Issues</a> for details on AWT's threading model. @@ -1861,7 +1861,7 @@ * Returns an array of all the window listeners * registered on this window. * - * @return all of this window's <code>WindowListener</code>s + * @return all of this window's {@code WindowListener}s * or an empty array if no window * listeners are currently registered * @@ -1877,7 +1877,7 @@ * Returns an array of all the window focus listeners * registered on this window. * - * @return all of this window's <code>WindowFocusListener</code>s + * @return all of this window's {@code WindowFocusListener}s * or an empty array if no window focus * listeners are currently registered * @@ -1893,7 +1893,7 @@ * Returns an array of all the window state listeners * registered on this window. * - * @return all of this window's <code>WindowStateListener</code>s + * @return all of this window's {@code WindowStateListener}s * or an empty array if no window state * listeners are currently registered * @@ -1909,17 +1909,17 @@ /** * Returns an array of all the objects currently registered * as <code><em>Foo</em>Listener</code>s - * upon this <code>Window</code>. + * upon this {@code Window}. * <code><em>Foo</em>Listener</code>s are registered using the * <code>add<em>Foo</em>Listener</code> method. * * <p> * - * You can specify the <code>listenerType</code> argument + * You can specify the {@code listenerType} argument * with a class literal, such as * <code><em>Foo</em>Listener.class</code>. * For example, you can query a - * <code>Window</code> <code>w</code> + * {@code Window} {@code w} * for its window listeners with the following code: * * <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre> @@ -1928,14 +1928,14 @@ * * @param listenerType the type of listeners requested; this parameter * should specify an interface that descends from - * <code>java.util.EventListener</code> + * {@code java.util.EventListener} * @return an array of all objects registered as * <code><em>Foo</em>Listener</code>s on this window, * or an empty array if no such * listeners have been added - * @exception ClassCastException if <code>listenerType</code> + * @exception ClassCastException if {@code listenerType} * doesn't specify a class or interface that implements - * <code>java.util.EventListener</code> + * {@code java.util.EventListener} * @exception NullPointerException if {@code listenerType} is {@code null} * * @see #getWindowListeners @@ -1991,10 +1991,10 @@ /** * Processes events on this window. If the event is an - * <code>WindowEvent</code>, it invokes the - * <code>processWindowEvent</code> method, else it invokes its - * superclass's <code>processEvent</code>. - * <p>Note that if the event parameter is <code>null</code> + * {@code WindowEvent}, it invokes the + * {@code processWindowEvent} method, else it invokes its + * superclass's {@code processEvent}. + * <p>Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2033,10 +2033,10 @@ * following occurs: * <ul> * <li>A WindowListener object is registered via - * <code>addWindowListener</code> - * <li>Window events are enabled via <code>enableEvents</code> + * {@code addWindowListener} + * <li>Window events are enabled via {@code enableEvents} * </ul> - * <p>Note that if the event parameter is <code>null</code> + * <p>Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2082,10 +2082,10 @@ * following occurs: * <ul> * <li>a WindowFocusListener is registered via - * <code>addWindowFocusListener</code> - * <li>Window focus events are enabled via <code>enableEvents</code> + * {@code addWindowFocusListener} + * <li>Window focus events are enabled via {@code enableEvents} * </ul> - * <p>Note that if the event parameter is <code>null</code> + * <p>Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2111,17 +2111,17 @@ /** * Processes window state event occuring on this window by - * dispatching them to any registered <code>WindowStateListener</code> + * dispatching them to any registered {@code WindowStateListener} * objects. * NOTE: this method will not be called unless window state events * are enabled for this window. This happens when one of the * following occurs: * <ul> - * <li>a <code>WindowStateListener</code> is registered via - * <code>addWindowStateListener</code> - * <li>window state events are enabled via <code>enableEvents</code> + * <li>a {@code WindowStateListener} is registered via + * {@code addWindowStateListener} + * <li>window state events are enabled via {@code enableEvents} * </ul> - * <p>Note that if the event parameter is <code>null</code> + * <p>Note that if the event parameter is {@code null} * the behavior is unspecified and may result in an * exception. * @@ -2145,7 +2145,7 @@ /** * Implements a debugging hook -- checks to see if * the user has typed <i>control-shift-F1</i>. If so, - * the list of child windows is dumped to <code>System.out</code>. + * the list of child windows is dumped to {@code System.out}. * @param e the keyboard event */ void preProcessKeyEvent(KeyEvent e) { @@ -2176,21 +2176,21 @@ * automatically become always-on-top. If a window ceases to be * always-on-top, the windows that it owns will no longer be * always-on-top. When an always-on-top window is sent {@link #toBack - * toBack}, its always-on-top state is set to <code>false</code>. + * toBack}, its always-on-top state is set to {@code false}. * * <p> When this method is called on a window with a value of - * <code>true</code>, and the window is visible and the platform + * {@code true}, and the window is visible and the platform * supports always-on-top for this window, the window is immediately * brought forward, "sticking" it in the top-most position. If the * window isn`t currently visible, this method sets the always-on-top - * state to <code>true</code> but does not bring the window forward. + * state to {@code true} but does not bring the window forward. * When the window is later shown, it will be always-on-top. * * <p> When this method is called on a window with a value of - * <code>false</code> the always-on-top state is set to normal. The + * {@code false} the always-on-top state is set to normal. The * window remains in the top-most position but it`s z-order can be * changed as for any other window. Calling this method with a value - * of <code>false</code> on a window that has a normal state has no + * of {@code false} on a window that has a normal state has no * effect. Setting the always-on-top state to false has no effect on * the relative z-order of the windows if there are no other * always-on-top windows. @@ -2250,9 +2250,9 @@ * window. Some platforms may not support always-on-top windows, some * may support only some kinds of top-level windows; for example, * a platform may not support always-on-top modal dialogs. - * @return <code>true</code>, if the always-on-top mode is + * @return {@code true}, if the always-on-top mode is * supported by the toolkit and for this window, - * <code>false</code>, if always-on-top mode is not supported + * {@code false}, if always-on-top mode is not supported * for this window or toolkit doesn't support always-on-top windows. * @see #setAlwaysOnTop(boolean) * @see Toolkit#isAlwaysOnTopSupported @@ -2265,8 +2265,8 @@ /** * Returns whether this window is an always-on-top window. - * @return <code>true</code>, if the window is in always-on-top state, - * <code>false</code> otherwise + * @return {@code true}, if the window is in always-on-top state, + * {@code false} otherwise * @see #setAlwaysOnTop * @since 1.5 */ @@ -2294,7 +2294,7 @@ /** * Returns the child Component of this Window that will receive the focus * when this Window is focused. If this Window is currently focused, this - * method returns the same Component as <code>getFocusOwner()</code>. If + * method returns the same Component as {@code getFocusOwner()}. If * this Window is not focused, then the child Component that most recently * requested focus will be returned. If no child Component has ever * requested focus, and this is a focusable Window, then this Window's @@ -2359,8 +2359,8 @@ } /** - * Gets a focus traversal key for this Window. (See <code> - * setFocusTraversalKeys</code> for a full description of each key.) + * Gets a focus traversal key for this Window. (See {@code + * setFocusTraversalKeys} for a full description of each key.) * <p> * If the traversal key has not been explicitly set for this Window, * then this Window's parent's traversal key is returned. If the @@ -2419,10 +2419,10 @@ } /** - * Always returns <code>true</code> because all Windows must be roots of a + * Always returns {@code true} because all Windows must be roots of a * focus traversal cycle. * - * @return <code>true</code> + * @return {@code true} * @see #setFocusCycleRoot * @see Container#setFocusTraversalPolicy * @see Container#getFocusTraversalPolicy @@ -2433,10 +2433,10 @@ } /** - * Always returns <code>null</code> because Windows have no ancestors; they + * Always returns {@code null} because Windows have no ancestors; they * represent the top of the Component hierarchy. * - * @return <code>null</code> + * @return {@code null} * @see Container#isFocusCycleRoot() * @since 1.4 */ @@ -2448,16 +2448,16 @@ * Returns whether this Window can become the focused Window, that is, * whether this Window or any of its subcomponents can become the focus * owner. For a Frame or Dialog to be focusable, its focusable Window state - * must be set to <code>true</code>. For a Window which is not a Frame or + * must be set to {@code true}. For a Window which is not a Frame or * Dialog to be focusable, its focusable Window state must be set to - * <code>true</code>, its nearest owning Frame or Dialog must be + * {@code true}, its nearest owning Frame or Dialog must be * showing on the screen, and it must contain at least one Component in * its focus traversal cycle. If any of these conditions is not met, then * neither this Window nor any of its subcomponents can become the focus * owner. * - * @return <code>true</code> if this Window can be the focused Window; - * <code>false</code> otherwise + * @return {@code true} if this Window can be the focused Window; + * {@code false} otherwise * @see #getFocusableWindowState * @see #setFocusableWindowState * @see #isShowing @@ -2497,16 +2497,16 @@ /** * Returns whether this Window can become the focused Window if it meets - * the other requirements outlined in <code>isFocusableWindow</code>. If - * this method returns <code>false</code>, then - * <code>isFocusableWindow</code> will return <code>false</code> as well. - * If this method returns <code>true</code>, then - * <code>isFocusableWindow</code> may return <code>true</code> or - * <code>false</code> depending upon the other requirements which must be + * the other requirements outlined in {@code isFocusableWindow}. If + * this method returns {@code false}, then + * {@code isFocusableWindow} will return {@code false} as well. + * If this method returns {@code true}, then + * {@code isFocusableWindow} may return {@code true} or + * {@code false} depending upon the other requirements which must be * met in order for a Window to be focusable. * <p> * By default, all Windows have a focusable Window state of - * <code>true</code>. + * {@code true}. * * @return whether this Window can be the focused Window * @see #isFocusableWindow @@ -2521,25 +2521,25 @@ /** * Sets whether this Window can become the focused Window if it meets - * the other requirements outlined in <code>isFocusableWindow</code>. If - * this Window's focusable Window state is set to <code>false</code>, then - * <code>isFocusableWindow</code> will return <code>false</code>. If this - * Window's focusable Window state is set to <code>true</code>, then - * <code>isFocusableWindow</code> may return <code>true</code> or - * <code>false</code> depending upon the other requirements which must be + * the other requirements outlined in {@code isFocusableWindow}. If + * this Window's focusable Window state is set to {@code false}, then + * {@code isFocusableWindow} will return {@code false}. If this + * Window's focusable Window state is set to {@code true}, then + * {@code isFocusableWindow} may return {@code true} or + * {@code false} depending upon the other requirements which must be * met in order for a Window to be focusable. * <p> - * Setting a Window's focusability state to <code>false</code> is the + * Setting a Window's focusability state to {@code false} is the * standard mechanism for an application to identify to the AWT a Window * which will be used as a floating palette or toolbar, and thus should be * a non-focusable Window. * - * Setting the focusability state on a visible <code>Window</code> + * Setting the focusability state on a visible {@code Window} * can have a delayed effect on some platforms — the actual - * change may happen only when the <code>Window</code> becomes + * change may happen only when the {@code Window} becomes * hidden and then visible again. To ensure consistent behavior - * across platforms, set the <code>Window</code>'s focusable state - * when the <code>Window</code> is invisible and then show it. + * across platforms, set the {@code Window}'s focusable state + * when the {@code Window} is invisible and then show it. * * @param focusableWindowState whether this Window can be the focused * Window @@ -2726,7 +2726,7 @@ /** * @deprecated As of JDK version 1.1 - * replaced by <code>dispatchEvent(AWTEvent)</code>. + * replaced by {@code dispatchEvent(AWTEvent)}. */ @Deprecated public boolean postEvent(Event e) { @@ -2876,22 +2876,22 @@ /** * Writes default serializable fields to stream. Writes - * a list of serializable <code>WindowListener</code>s and - * <code>WindowFocusListener</code>s as optional data. + * a list of serializable {@code WindowListener}s and + * {@code WindowFocusListener}s as optional data. * Writes a list of child windows as optional data. * Writes a list of icon images as optional data * - * @param s the <code>ObjectOutputStream</code> to write - * @serialData <code>null</code> terminated sequence of - * 0 or more pairs; the pair consists of a <code>String</code> - * and and <code>Object</code>; the <code>String</code> + * @param s the {@code ObjectOutputStream} to write + * @serialData {@code null} terminated sequence of + * 0 or more pairs; the pair consists of a {@code String} + * and {@code Object}; the {@code String} * indicates the type of object and is one of the following: - * <code>windowListenerK</code> indicating a - * <code>WindowListener</code> object; - * <code>windowFocusWindowK</code> indicating a - * <code>WindowFocusListener</code> object; - * <code>ownedWindowK</code> indicating a child - * <code>Window</code> object + * {@code windowListenerK} indicating a + * {@code WindowListener} object; + * {@code windowFocusWindowK} indicating a + * {@code WindowFocusListener} object; + * {@code ownedWindowK} indicating a child + * {@code Window} object * * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener) * @see Component#windowListenerK @@ -3029,16 +3029,16 @@ } /** - * Reads the <code>ObjectInputStream</code> and an optional + * Reads the {@code ObjectInputStream} and an optional * list of listeners to receive various events fired by * the component; also reads a list of - * (possibly <code>null</code>) child windows. + * (possibly {@code null}) child windows. * Unrecognized keys or values will be ignored. * - * @param s the <code>ObjectInputStream</code> to read + * @param s the {@code ObjectInputStream} to read * @exception HeadlessException if - * <code>GraphicsEnvironment.isHeadless</code> returns - * <code>true</code> + * {@code GraphicsEnvironment.isHeadless} returns + * {@code true} * @see java.awt.GraphicsEnvironment#isHeadless * @see #writeObject */ @@ -3100,7 +3100,7 @@ /** * This class implements accessibility support for the - * <code>Window</code> class. It provides an implementation of the + * {@code Window} class. It provides an implementation of the * Java Accessibility API appropriate to window user-interface elements. * @since 1.3 */ @@ -3186,7 +3186,7 @@ * not changed. * <p> * <b>Note</b>: If the lower edge of the window is out of the screen, - * then the window is placed to the side of the <code>Component</code> + * then the window is placed to the side of the {@code Component} * that is closest to the center of the screen. So if the * component is on the right part of the screen, the window * is placed to its left, and vice versa. @@ -3289,7 +3289,7 @@ * Creates a new strategy for multi-buffering on this component. * Multi-buffering is useful for rendering performance. This method * attempts to create the best strategy available with the number of - * buffers supplied. It will always create a <code>BufferStrategy</code> + * buffers supplied. It will always create a {@code BufferStrategy} * with that number of buffers. * A page-flipping strategy is attempted first, then a blitting strategy * using accelerated buffers. Finally, an unaccelerated blitting @@ -3318,13 +3318,13 @@ * is called, the existing buffer strategy for this component is discarded. * @param numBuffers number of buffers to create, including the front buffer * @param caps the required capabilities for creating the buffer strategy; - * cannot be <code>null</code> + * cannot be {@code null} * @exception AWTException if the capabilities supplied could not be * supported or met; this may happen, for example, if there is not enough * accelerated memory currently available, or if page flipping is specified * but not possible. * @exception IllegalArgumentException if numBuffers is less than 1, or if - * caps is <code>null</code> + * caps is {@code null} * @see #getBufferStrategy * @since 1.4 */ @@ -3334,8 +3334,8 @@ } /** - * Returns the <code>BufferStrategy</code> used by this component. This - * method will return null if a <code>BufferStrategy</code> has not yet + * Returns the {@code BufferStrategy} used by this component. This + * method will return null if a {@code BufferStrategy} has not yet * been created or has been disposed. * * @return the buffer strategy used by this component @@ -3376,7 +3376,7 @@ /** * Sets whether this Window should appear at the default location for the * native windowing system or at the current location (returned by - * <code>getLocation</code>) the next time the Window is made visible. + * {@code getLocation}) the next time the Window is made visible. * This behavior resembles a native window shown without programmatically * setting its location. Most windowing systems cascade windows if their * locations are not explicitly set. The actual location is determined once the @@ -3386,8 +3386,8 @@ * "java.awt.Window.locationByPlatform" to "true", though calls to this method * take precedence. * <p> - * Calls to <code>setVisible</code>, <code>setLocation</code> and - * <code>setBounds</code> after calling <code>setLocationByPlatform</code> clear + * Calls to {@code setVisible}, {@code setLocation} and + * {@code setBounds} after calling {@code setLocationByPlatform} clear * this property of the Window. * <p> * For example, after the following code is executed: @@ -3397,7 +3397,7 @@ * boolean flag = isLocationByPlatform(); * </blockquote></pre> * The window will be shown at platform's default location and - * <code>flag</code> will be <code>false</code>. + * {@code flag} will be {@code false}. * <p> * In the following sample: * <pre><blockquote> @@ -3406,13 +3406,13 @@ * boolean flag = isLocationByPlatform(); * setVisible(true); * </blockquote></pre> - * The window will be shown at (10, 10) and <code>flag</code> will be - * <code>false</code>. + * The window will be shown at (10, 10) and {@code flag} will be + * {@code false}. * - * @param locationByPlatform <code>true</code> if this Window should appear - * at the default location, <code>false</code> if at the current location - * @throws <code>IllegalComponentStateException</code> if the window - * is showing on screen and locationByPlatform is <code>true</code>. + * @param locationByPlatform {@code true} if this Window should appear + * at the default location, {@code false} if at the current location + * @throws {@code IllegalComponentStateException} if the window + * is showing on screen and locationByPlatform is {@code true}. * @see #setLocation * @see #isShowing * @see #setVisible @@ -3430,9 +3430,9 @@ } /** - * Returns <code>true</code> if this Window will appear at the default location + * Returns {@code true} if this Window will appear at the default location * for the native windowing system the next time this Window is made visible. - * This method always returns <code>false</code> if the Window is showing on the + * This method always returns {@code false} if the Window is showing on the * screen. * * @return whether this Window will appear at the default location @@ -3509,8 +3509,8 @@ /** * Determines whether this component will be displayed on the screen. - * @return <code>true</code> if the component and all of its ancestors - * until a toplevel window are visible, <code>false</code> otherwise + * @return {@code true} if the component and all of its ancestors + * until a toplevel window are visible, {@code false} otherwise */ boolean isRecursivelyVisible() { // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible.
--- a/src/share/classes/java/io/BufferedInputStream.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/io/BufferedInputStream.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -50,7 +50,15 @@ public class BufferedInputStream extends FilterInputStream { - private static int defaultBufferSize = 8192; + private static int DEFAULT_BUFFER_SIZE = 8192; + + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; /** * The internal buffer array where the data is stored. When necessary, @@ -172,7 +180,7 @@ * @param in the underlying input stream. */ public BufferedInputStream(InputStream in) { - this(in, defaultBufferSize); + this(in, DEFAULT_BUFFER_SIZE); } /** @@ -215,8 +223,11 @@ } else if (buffer.length >= marklimit) { markpos = -1; /* buffer got too big, invalidate mark */ pos = 0; /* drop buffer contents */ + } else if (buffer.length >= MAX_BUFFER_SIZE) { + throw new OutOfMemoryError("Required array size too large"); } else { /* grow buffer */ - int nsz = pos * 2; + int nsz = (pos <= MAX_BUFFER_SIZE - pos) ? + pos * 2 : MAX_BUFFER_SIZE; if (nsz > marklimit) nsz = marklimit; byte nbuf[] = new byte[nsz];
--- a/src/share/classes/java/io/RandomAccessFile.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/io/RandomAccessFile.java Tue Aug 27 12:27:31 2013 -0400 @@ -518,7 +518,15 @@ * @exception IOException if {@code pos} is less than * {@code 0} or if an I/O error occurs. */ - public native void seek(long pos) throws IOException; + public void seek(long pos) throws IOException { + if (pos < 0) { + throw new IOException("Negative seek offset"); + } else { + seek0(pos); + } + } + + private native void seek0(long pos) throws IOException; /** * Returns the length of this file.
--- a/src/share/classes/java/lang/AbstractStringBuilder.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/lang/AbstractStringBuilder.java Tue Aug 27 12:27:31 2013 -0400 @@ -1307,7 +1307,7 @@ * specified substring, starting at the specified index. The integer * returned is the smallest value {@code k} for which: * <blockquote><pre> - * k >= Math.min(fromIndex, str.length()) && + * k >= Math.min(fromIndex, this.length()) && * this.toString().startsWith(str, k) * </pre></blockquote> * If no such value of <i>k</i> exists, then -1 is returned. @@ -1346,7 +1346,7 @@ * specified substring. The integer returned is the largest value <i>k</i> * such that: * <blockquote><pre> - * k <= Math.min(fromIndex, str.length()) && + * k <= Math.min(fromIndex, this.length()) && * this.toString().startsWith(str, k) * </pre></blockquote> * If no such value of <i>k</i> exists, then -1 is returned.
--- a/src/share/classes/java/lang/Class.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/lang/Class.java Tue Aug 27 12:27:31 2013 -0400 @@ -3338,8 +3338,16 @@ * @since 1.8 */ public AnnotatedType getAnnotatedSuperclass() { - return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this); -} + if (this == Object.class || + isInterface() || + isArray() || + isPrimitive() || + this == Void.TYPE) { + return null; + } + + return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this); + } /** * Returns an array of AnnotatedType objects that represent the use of types to
--- a/src/share/classes/java/lang/Math.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/lang/Math.java Tue Aug 27 12:27:31 2013 -0400 @@ -698,11 +698,8 @@ return 0; } - private static Random randomNumberGenerator; - - private static synchronized Random initRNG() { - Random rnd = randomNumberGenerator; - return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; + private static final class RandomNumberGeneratorHolder { + static final Random randomNumberGenerator = new Random(); } /** @@ -729,9 +726,7 @@ * @see Random#nextDouble() */ public static double random() { - Random rnd = randomNumberGenerator; - if (rnd == null) rnd = initRNG(); - return rnd.nextDouble(); + return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); } /**
--- a/src/share/classes/java/lang/StrictMath.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/lang/StrictMath.java Tue Aug 27 12:27:31 2013 -0400 @@ -678,11 +678,8 @@ return Math.round(a); } - private static Random randomNumberGenerator; - - private static synchronized Random initRNG() { - Random rnd = randomNumberGenerator; - return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; + private static final class RandomNumberGeneratorHolder { + static final Random randomNumberGenerator = new Random(); } /** @@ -709,9 +706,7 @@ * @see Random#nextDouble() */ public static double random() { - Random rnd = randomNumberGenerator; - if (rnd == null) rnd = initRNG(); - return rnd.nextDouble(); + return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble(); } /**
--- a/src/share/classes/java/math/BigDecimal.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/math/BigDecimal.java Tue Aug 27 12:27:31 2013 -0400 @@ -2659,28 +2659,32 @@ if (ys == 0) return 1; - int sdiff = this.scale - val.scale; + long sdiff = (long)this.scale - val.scale; if (sdiff != 0) { // Avoid matching scales if the (adjusted) exponents differ - int xae = this.precision() - this.scale; // [-1] - int yae = val.precision() - val.scale; // [-1] + long xae = (long)this.precision() - this.scale; // [-1] + long yae = (long)val.precision() - val.scale; // [-1] if (xae < yae) return -1; if (xae > yae) return 1; BigInteger rb = null; if (sdiff < 0) { - if ( (xs == INFLATED || - (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) && + // The cases sdiff <= Integer.MIN_VALUE intentionally fall through. + if ( sdiff > Integer.MIN_VALUE && + (xs == INFLATED || + (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) && ys == INFLATED) { - rb = bigMultiplyPowerTen(-sdiff); + rb = bigMultiplyPowerTen((int)-sdiff); return rb.compareMagnitude(val.intVal); } } else { // sdiff > 0 - if ( (ys == INFLATED || - (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) && + // The cases sdiff > Integer.MAX_VALUE intentionally fall through. + if ( sdiff <= Integer.MAX_VALUE && + (ys == INFLATED || + (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) && xs == INFLATED) { - rb = val.bigMultiplyPowerTen(sdiff); + rb = val.bigMultiplyPowerTen((int)sdiff); return this.intVal.compareMagnitude(rb); } } @@ -4545,7 +4549,7 @@ if(cmp > 0) { // satisfy constraint (b) yscale -= 1; // [that is, divisor *= 10] int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { // assert newScale >= xscale int raise = checkScaleNonZero((long) mcp + yscale - xscale); long scaledXs; @@ -4626,7 +4630,7 @@ // return BigDecimal object whose scale will be set to 'scl'. int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); BigDecimal quotient; - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); long scaledXs; if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) { @@ -4673,7 +4677,7 @@ // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale)); @@ -4714,7 +4718,7 @@ // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale)); @@ -4745,7 +4749,7 @@ // return BigDecimal object whose scale will be set to 'scl'. BigDecimal quotient; int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp); - if (checkScaleNonZero((long) mcp + yscale) > xscale) { + if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) { int raise = checkScaleNonZero((long) mcp + yscale - xscale); BigInteger rb = bigMultiplyPowerTen(xs,raise); quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
--- a/src/share/classes/java/math/BigInteger.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/math/BigInteger.java Tue Aug 27 12:27:31 2013 -0400 @@ -2109,7 +2109,7 @@ // This is a quick way to approximate the size of the result, // similar to doing log2[n] * exponent. This will give an upper bound // of how big the result can be, and which algorithm to use. - int scaleFactor = remainingBits * exponent; + long scaleFactor = (long)remainingBits * exponent; // Use slightly different algorithms for small and large operands. // See if the result will safely fit into a long. (Largest 2^63-1)
--- a/src/share/classes/java/net/IDN.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/net/IDN.java Tue Aug 27 12:27:31 2013 -0400 @@ -113,11 +113,18 @@ int p = 0, q = 0; StringBuffer out = new StringBuffer(); + if (isRootLabel(input)) { + return "."; + } + while (p < input.length()) { q = searchDots(input, p); out.append(toASCIIInternal(input.substring(p, q), flag)); + if (q != (input.length())) { + // has more labels, or keep the trailing dot as at present + out.append('.'); + } p = q + 1; - if (p < input.length()) out.append('.'); } return out.toString(); @@ -167,11 +174,18 @@ int p = 0, q = 0; StringBuffer out = new StringBuffer(); + if (isRootLabel(input)) { + return "."; + } + while (p < input.length()) { q = searchDots(input, p); out.append(toUnicodeInternal(input.substring(p, q), flag)); + if (q != (input.length())) { + // has more labels, or keep the trailing dot as at present + out.append('.'); + } p = q + 1; - if (p < input.length()) out.append('.'); } return out.toString(); @@ -263,6 +277,13 @@ dest = new StringBuffer(label); } + // step 8, move forward to check the smallest number of the code points + // the length must be inside 1..63 + if (dest.length() == 0) { + throw new IllegalArgumentException( + "Empty label is not a legal name"); + } + // step 3 // Verify the absence of non-LDH ASCII code points // 0..0x2c, 0x2e..0x2f, 0x3a..0x40, 0x5b..0x60, 0x7b..0x7f @@ -311,7 +332,7 @@ // step 8 // the length must be inside 1..63 - if(dest.length() > MAX_LABEL_LENGTH){ + if (dest.length() > MAX_LABEL_LENGTH) { throw new IllegalArgumentException("The label in the input is too long"); } @@ -409,8 +430,7 @@ private static int searchDots(String s, int start) { int i; for (i = start; i < s.length(); i++) { - char c = s.charAt(i); - if (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61') { + if (isLabelSeparator(s.charAt(i))) { break; } } @@ -418,6 +438,19 @@ return i; } + // + // to check if a string is a root label, ".". + // + private static boolean isRootLabel(String s) { + return (s.length() == 1 && isLabelSeparator(s.charAt(0))); + } + + // + // to check if a character is a label separator, i.e. a dot character. + // + private static boolean isLabelSeparator(char c) { + return (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61'); + } // // to check if a string only contains US-ASCII code point
--- a/src/share/classes/java/rmi/server/RMISocketFactory.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/rmi/server/RMISocketFactory.java Tue Aug 27 12:27:31 2013 -0400 @@ -50,13 +50,13 @@ * @implNote * <p>You can use the {@code RMISocketFactory} class to create a server socket that * is bound to a specific address, restricting the origin of requests. For example, - * the following code implements a socket factory that binds server sockets to the + * the following code implements a socket factory that binds server sockets to an IPv4 * loopback address. This restricts RMI to processing requests only from the local host. * * <pre>{@code * class LoopbackSocketFactory extends RMISocketFactory { * public ServerSocket createServerSocket(int port) throws IOException { - * return new ServerSocket(port, 5, InetAddress.getLoopbackAddress()); + * return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1")); * } * * public Socket createSocket(String host, int port) throws IOException { @@ -72,8 +72,8 @@ * }</pre> * * Set the {@code java.rmi.server.hostname} system property - * to a host name (typically {@code localhost}) that resolves to the loopback - * interface to ensure that the generated stubs use the right network interface. + * to {@code 127.0.0.1} to ensure that the generated stubs connect to the right + * network interface. * * @author Ann Wollrath * @author Peter Jones
--- a/src/share/classes/java/time/chrono/JapaneseEra.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/time/chrono/JapaneseEra.java Tue Aug 27 12:27:31 2013 -0400 @@ -107,7 +107,7 @@ * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) * which has the value -1. */ - public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 9, 8)); + public static final JapaneseEra MEIJI = new JapaneseEra(-1, LocalDate.of(1868, 1, 1)); /** * The singleton instance for the 'Taisho' era (1912-07-30 - 1926-12-24) * which has the value 0.
--- a/src/share/classes/java/util/ArrayDeque.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/ArrayDeque.java Tue Aug 27 12:27:31 2013 -0400 @@ -888,6 +888,19 @@ elements[i] = s.readObject(); } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * deque. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and + * {@link Spliterator#NONNULL}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator<E> spliterator() { return new DeqSpliterator<E>(this, -1, -1); }
--- a/src/share/classes/java/util/ArrayList.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/ArrayList.java Tue Aug 27 12:27:31 2013 -0400 @@ -1238,6 +1238,20 @@ } } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * list. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ + @Override public Spliterator<E> spliterator() { return new ArrayListSpliterator<>(this, 0, -1, 0); }
--- a/src/share/classes/java/util/Collections.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/Collections.java Tue Aug 27 12:27:31 2013 -0400 @@ -4508,7 +4508,6 @@ } @Override public void sort(Comparator<? super E> c) { - Objects.requireNonNull(c); } // Override default methods in Collection
--- a/src/share/classes/java/util/ComparableTimSort.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/ComparableTimSort.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,4 +1,5 @@ /* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Google Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -146,7 +147,7 @@ */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; }
--- a/src/share/classes/java/util/Formatter.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/Formatter.java Tue Aug 27 12:27:31 2013 -0400 @@ -4196,7 +4196,7 @@ case DateTime.CENTURY: // 'C' (00 - 99) case DateTime.YEAR_2: // 'y' (00 - 99) case DateTime.YEAR_4: { // 'Y' (0000 - 9999) - int i = t.get(ChronoField.YEAR); + int i = t.get(ChronoField.YEAR_OF_ERA); int size = 2; switch (c) { case DateTime.CENTURY:
--- a/src/share/classes/java/util/HashSet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/HashSet.java Tue Aug 27 12:27:31 2013 -0400 @@ -312,6 +312,18 @@ } } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * set. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#DISTINCT}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator<E> spliterator() { return new HashMap.KeySpliterator<E,Object>(map, 0, -1, 0, 0); }
--- a/src/share/classes/java/util/LinkedHashMap.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/LinkedHashMap.java Tue Aug 27 12:27:31 2013 -0400 @@ -129,10 +129,20 @@ * exception for its correctness: <i>the fail-fast behavior of iterators * should be used only to detect bugs.</i> * + * <p>The spliterators returned by the spliterator method of the collections + * returned by all of this class's collection view methods are + * <em><a href="Spliterator.html#binding">late-binding</a></em>, + * <em>fail-fast</em>, and additionally report {@link Spliterator#ORDERED}. + * * <p>This class is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * + * @implNote + * The spliterators returned by the spliterator method of the collections + * returned by all of this class's collection view methods are created from + * the iterators of the corresponding collections. + * * @param <K> the type of keys maintained by this map * @param <V> the type of mapped values *
--- a/src/share/classes/java/util/LinkedHashSet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/LinkedHashSet.java Tue Aug 27 12:27:31 2013 -0400 @@ -170,13 +170,23 @@ } /** - * Creates a {@code Spliterator}, over the elements in this set, that - * reports {@code SIZED}, {@code DISTINCT} and {@code ORDERED}. - * Overriding implementations are expected to document if the - * {@code Spliterator} reports any additional and relevant characteristic - * values. + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@code Spliterator} over the elements in this set. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#DISTINCT}, and {@code ORDERED}. Implementations + * should document the reporting of additional characteristic values. + * + * @implNote + * The implementation creates a + * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator + * from the set's {@code Iterator}. The spliterator inherits the + * <em>fail-fast</em> properties of the set's iterator. + * The created {@code Spliterator} additionally reports + * {@link Spliterator#SUBSIZED}. * * @return a {@code Spliterator} over the elements in this set + * @since 1.8 */ @Override public Spliterator<E> spliterator() {
--- a/src/share/classes/java/util/LinkedList.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/LinkedList.java Tue Aug 27 12:27:31 2013 -0400 @@ -1149,6 +1149,23 @@ linkLast((E)s.readObject()); } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * list. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#ORDERED}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * @implNote + * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED} + * and implements {@code trySplit} to permit limited parallelism.. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ + @Override public Spliterator<E> spliterator() { return new LLSpliterator<E>(this, -1, 0); }
--- a/src/share/classes/java/util/List.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/List.java Tue Aug 27 12:27:31 2013 -0400 @@ -671,7 +671,7 @@ * The default implementation creates a * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator * from the list's {@code Iterator}. The spliterator inherits the - * <em>fail-fast</em> properties of the collection's iterator. + * <em>fail-fast</em> properties of the list's iterator. * * @implNote * The created {@code Spliterator} additionally reports
--- a/src/share/classes/java/util/PriorityQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/PriorityQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -795,6 +795,19 @@ heapify(); } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * queue. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#NONNULL}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public final Spliterator<E> spliterator() { return new PriorityQueueSpliterator<E>(this, 0, -1, 0); }
--- a/src/share/classes/java/util/Set.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/Set.java Tue Aug 27 12:27:31 2013 -0400 @@ -394,7 +394,7 @@ * The default implementation creates a * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator * from the set's {@code Iterator}. The spliterator inherits the - * <em>fail-fast</em> properties of the collection's iterator. + * <em>fail-fast</em> properties of the set's iterator. * * @implNote * The created {@code Spliterator} additionally reports
--- a/src/share/classes/java/util/SortedSet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/SortedSet.java Tue Aug 27 12:27:31 2013 -0400 @@ -238,7 +238,7 @@ * The default implementation creates a * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator * from the sorted set's {@code Iterator}. The spliterator inherits the - * <em>fail-fast</em> properties of the collection's iterator. The + * <em>fail-fast</em> properties of the set's iterator. The * spliterator's comparator is the same as the sorted set's comparator. * * @implNote
--- a/src/share/classes/java/util/Spliterator.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/Spliterator.java Tue Aug 27 12:27:31 2013 -0400 @@ -74,7 +74,11 @@ * source prior to binding are reflected when the Spliterator is traversed. * After binding a Spliterator should, on a best-effort basis, throw * {@link ConcurrentModificationException} if structural interference is - * detected. Spliterators that do this are called <em>fail-fast</em>. + * detected. Spliterators that do this are called <em>fail-fast</em>. The + * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a + * Spliterator may optimize traversal and check for structural interference + * after all elements have been traversed, rather than checking per-element and + * failing immediately. * * <p>Spliterators can provide an estimate of the number of remaining elements * via the {@link #estimateSize} method. Ideally, as reflected in characteristic
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/util/SplittableRandom.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,1002 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util; + +import java.security.SecureRandom; +import java.net.InetAddress; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.IntConsumer; +import java.util.function.LongConsumer; +import java.util.function.DoubleConsumer; +import java.util.stream.StreamSupport; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.DoubleStream; + +/** + * A generator of uniform pseudorandom values applicable for use in + * (among other contexts) isolated parallel computations that may + * generate subtasks. Class {@code SplittableRandom} supports methods for + * producing pseudorandom numbers of type {@code int}, {@code long}, + * and {@code double} with similar usages as for class + * {@link java.util.Random} but differs in the following ways: + * + * <ul> + * + * <li>Series of generated values pass the DieHarder suite testing + * independence and uniformity properties of random number generators. + * (Most recently validated with <a + * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version + * 3.31.1</a>.) These tests validate only the methods for certain + * types and ranges, but similar properties are expected to hold, at + * least approximately, for others as well. The <em>period</em> + * (length of any series of generated values before it repeats) is at + * least 2<sup>64</sup>. </li> + * + * <li> Method {@link #split} constructs and returns a new + * SplittableRandom instance that shares no mutable state with the + * current instance. However, with very high probability, the + * values collectively generated by the two objects have the same + * statistical properties as if the same quantity of values were + * generated by a single thread using a single {@code + * SplittableRandom} object. </li> + * + * <li>Instances of SplittableRandom are <em>not</em> thread-safe. + * They are designed to be split, not shared, across threads. For + * example, a {@link java.util.concurrent.ForkJoinTask + * fork/join-style} computation using random numbers might include a + * construction of the form {@code new + * Subtask(aSplittableRandom.split()).fork()}. + * + * <li>This class provides additional methods for generating random + * streams, that employ the above techniques when used in {@code + * stream.parallel()} mode.</li> + * + * </ul> + * + * <p>Instances of {@code SplittableRandom} are not cryptographically + * secure. Consider instead using {@link java.security.SecureRandom} + * in security-sensitive applications. Additionally, + * default-constructed instances do not use a cryptographically random + * seed unless the {@linkplain System#getProperty system property} + * {@code java.util.secureRandomSeed} is set to {@code true}. + * + * @author Guy Steele + * @author Doug Lea + * @since 1.8 + */ +public final class SplittableRandom { + + /* + * Implementation Overview. + * + * This algorithm was inspired by the "DotMix" algorithm by + * Leiserson, Schardl, and Sukha "Deterministic Parallel + * Random-Number Generation for Dynamic-Multithreading Platforms", + * PPoPP 2012, as well as those in "Parallel random numbers: as + * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It + * differs mainly in simplifying and cheapening operations. + * + * The primary update step (method nextSeed()) is to add a + * constant ("gamma") to the current (64 bit) seed, forming a + * simple sequence. The seed and the gamma values for any two + * SplittableRandom instances are highly likely to be different. + * + * Methods nextLong, nextInt, and derivatives do not return the + * sequence (seed) values, but instead a hash-like bit-mix of + * their bits, producing more independently distributed sequences. + * For nextLong, the mix64 bit-mixing function computes the same + * value as the "64-bit finalizer" function in Austin Appleby's + * MurmurHash3 algorithm. See + * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which + * comments: "The constants for the finalizers were generated by a + * simple simulated-annealing algorithm, and both avalanche all + * bits of 'h' to within 0.25% bias." The mix32 function is + * equivalent to (int)(mix64(seed) >>> 32), but faster because it + * omits a step that doesn't contribute to result. + * + * The split operation uses the current generator to form the seed + * and gamma for another SplittableRandom. To conservatively + * avoid potential correlations between seed and value generation, + * gamma selection (method nextGamma) uses the "Mix13" constants + * for MurmurHash3 described by David Stafford + * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) + * To avoid potential weaknesses in bit-mixing transformations, we + * restrict gammas to odd values with at least 12 and no more than + * 52 bits set. Rather than rejecting candidates with too few or + * too many bits set, method nextGamma flips some bits (which has + * the effect of mapping at most 4 to any given gamma value). + * This reduces the effective set of 64bit odd gamma values by + * about 2<sup>14</sup>, a very tiny percentage, and serves as an + * automated screening for sequence constant selection that is + * left as an empirical decision in some other hashing and crypto + * algorithms. + * + * The resulting generator thus transforms a sequence in which + * (typically) many bits change on each step, with an inexpensive + * mixer with good (but less than cryptographically secure) + * avalanching. + * + * The default (no-argument) constructor, in essence, invokes + * split() for a common "seeder" SplittableRandom. Unlike other + * cases, this split must be performed in a thread-safe manner, so + * we use an AtomicLong to represent the seed rather than use an + * explicit SplittableRandom. To bootstrap the seeder, we start + * off using a seed based on current time and host unless the + * java.util.secureRandomSeed property is set. This serves as a + * slimmed-down (and insecure) variant of SecureRandom that also + * avoids stalls that may occur when using /dev/random. + * + * It is a relatively simple matter to apply the basic design here + * to use 128 bit seeds. However, emulating 128bit arithmetic and + * carrying around twice the state add more overhead than appears + * warranted for current usages. + * + * File organization: First the non-public methods that constitute + * the main algorithm, then the main public methods, followed by + * some custom spliterator classes needed for stream methods. + */ + + /** + * The initial gamma value for (unsplit) SplittableRandoms. Must + * be odd with at least 12 and no more than 52 bits set. Currently + * set to the golden ratio scaled to 64bits. + */ + private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L; + + /** + * The least non-zero value returned by nextDouble(). This value + * is scaled by a random value of 53 bits to produce a result. + */ + private static final double DOUBLE_UNIT = 1.0 / (1L << 53); + + /** + * The seed. Updated only via method nextSeed. + */ + private long seed; + + /** + * The step value. + */ + private final long gamma; + + /** + * Internal constructor used by all others except default constructor. + */ + private SplittableRandom(long seed, long gamma) { + this.seed = seed; + this.gamma = gamma; + } + + /** + * Computes MurmurHash3 64bit mix function. + */ + private static long mix64(long z) { + z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; + z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L; + return z ^ (z >>> 33); + } + + /** + * Returns the 32 high bits of mix64(z) as int. + */ + private static int mix32(long z) { + z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; + return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32); + } + + /** + * Returns the gamma value to use for a new split instance. + */ + private static long nextGamma(long z) { + z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13" + z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; + z = (z ^ (z >>> 31)) | 1L; // force to be odd + int n = Long.bitCount(z); // ensure enough 0 and 1 bits + return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z; + } + + /** + * Adds gamma to seed. + */ + private long nextSeed() { + return seed += gamma; + } + + /** + * The seed generator for default constructors. + */ + private static final AtomicLong seeder = new AtomicLong(initialSeed()); + + private static long initialSeed() { + String pp = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.secureRandomSeed")); + if (pp != null && pp.equalsIgnoreCase("true")) { + byte[] seedBytes = java.security.SecureRandom.getSeed(8); + long s = (long)(seedBytes[0]) & 0xffL; + for (int i = 1; i < 8; ++i) + s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); + return s; + } + int hh = 0; // hashed host address + try { + hh = InetAddress.getLocalHost().hashCode(); + } catch (Exception ignore) { + } + return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^ + mix64(System.nanoTime())); + } + + // IllegalArgumentException messages + static final String BadBound = "bound must be positive"; + static final String BadRange = "bound must be greater than origin"; + static final String BadSize = "size must be non-negative"; + + /* + * Internal versions of nextX methods used by streams, as well as + * the public nextX(origin, bound) methods. These exist mainly to + * avoid the need for multiple versions of stream spliterators + * across the different exported forms of streams. + */ + + /** + * The form of nextLong used by LongStream Spliterators. If + * origin is greater than bound, acts as unbounded form of + * nextLong, else as bounded form. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final long internalNextLong(long origin, long bound) { + /* + * Four Cases: + * + * 1. If the arguments indicate unbounded form, act as + * nextLong(). + * + * 2. If the range is an exact power of two, apply the + * associated bit mask. + * + * 3. If the range is positive, loop to avoid potential bias + * when the implicit nextLong() bound (2<sup>64</sup>) is not + * evenly divisible by the range. The loop rejects candidates + * computed from otherwise over-represented values. The + * expected number of iterations under an ideal generator + * varies from 1 to 2, depending on the bound. The loop itself + * takes an unlovable form. Because the first candidate is + * already available, we need a break-in-the-middle + * construction, which is concisely but cryptically performed + * within the while-condition of a body-less for loop. + * + * 4. Otherwise, the range cannot be represented as a positive + * long. The loop repeatedly generates unbounded longs until + * obtaining a candidate meeting constraints (with an expected + * number of iterations of less than two). + */ + + long r = mix64(nextSeed()); + if (origin < bound) { + long n = bound - origin, m = n - 1; + if ((n & m) == 0L) // power of two + r = (r & m) + origin; + else if (n > 0L) { // reject over-represented candidates + for (long u = r >>> 1; // ensure nonnegative + u + m - (r = u % n) < 0L; // rejection check + u = mix64(nextSeed()) >>> 1) // retry + ; + r += origin; + } + else { // range not representable as long + while (r < origin || r >= bound) + r = mix64(nextSeed()); + } + } + return r; + } + + /** + * The form of nextInt used by IntStream Spliterators. + * Exactly the same as long version, except for types. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final int internalNextInt(int origin, int bound) { + int r = mix32(nextSeed()); + if (origin < bound) { + int n = bound - origin, m = n - 1; + if ((n & m) == 0) + r = (r & m) + origin; + else if (n > 0) { + for (int u = r >>> 1; + u + m - (r = u % n) < 0; + u = mix32(nextSeed()) >>> 1) + ; + r += origin; + } + else { + while (r < origin || r >= bound) + r = mix32(nextSeed()); + } + } + return r; + } + + /** + * The form of nextDouble used by DoubleStream Spliterators. + * + * @param origin the least value, unless greater than bound + * @param bound the upper bound (exclusive), must not equal origin + * @return a pseudorandom value + */ + final double internalNextDouble(double origin, double bound) { + double r = (nextLong() >>> 11) * DOUBLE_UNIT; + if (origin < bound) { + r = r * (bound - origin) + origin; + if (r >= bound) // correct for rounding + r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + } + return r; + } + + /* ---------------- public methods ---------------- */ + + /** + * Creates a new SplittableRandom instance using the specified + * initial seed. SplittableRandom instances created with the same + * seed in the same program generate identical sequences of values. + * + * @param seed the initial seed + */ + public SplittableRandom(long seed) { + this(seed, INITIAL_GAMMA); + } + + /** + * Creates a new SplittableRandom instance that is likely to + * generate sequences of values that are statistically independent + * of those of any other instances in the current program; and + * may, and typically does, vary across program invocations. + */ + public SplittableRandom() { // emulate seeder.split() + this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA)); + } + + /** + * Constructs and returns a new SplittableRandom instance that + * shares no mutable state with this instance. However, with very + * high probability, the set of values collectively generated by + * the two objects has the same statistical properties as if the + * same quantity of values were generated by a single thread using + * a single SplittableRandom object. Either or both of the two + * objects may be further split using the {@code split()} method, + * and the same expected statistical properties apply to the + * entire set of generators constructed by such recursive + * splitting. + * + * @return the new SplittableRandom instance + */ + public SplittableRandom split() { + long s = nextSeed(); + return new SplittableRandom(s, nextGamma(s)); + } + + /** + * Returns a pseudorandom {@code int} value. + * + * @return a pseudorandom {@code int} value + */ + public int nextInt() { + return mix32(nextSeed()); + } + + /** + * Returns a pseudorandom {@code int} value between zero (inclusive) + * and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code int} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public int nextInt(int bound) { + if (bound <= 0) + throw new IllegalArgumentException(BadBound); + // Specialize internalNextInt for origin 0 + int r = mix32(nextSeed()); + int m = bound - 1; + if ((bound & m) == 0) // power of two + r &= m; + else { // reject over-represented candidates + for (int u = r >>> 1; + u + m - (r = u % bound) < 0; + u = mix32(nextSeed()) >>> 1) + ; + } + return r; + } + + /** + * Returns a pseudorandom {@code int} value between the specified + * origin (inclusive) and the specified bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code int} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public int nextInt(int origin, int bound) { + if (origin >= bound) + throw new IllegalArgumentException(BadRange); + return internalNextInt(origin, bound); + } + + /** + * Returns a pseudorandom {@code long} value. + * + * @return a pseudorandom {@code long} value + */ + public long nextLong() { + return mix64(nextSeed()); + } + + /** + * Returns a pseudorandom {@code long} value between zero (inclusive) + * and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code long} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public long nextLong(long bound) { + if (bound <= 0) + throw new IllegalArgumentException(BadBound); + // Specialize internalNextLong for origin 0 + long r = mix64(nextSeed()); + long m = bound - 1; + if ((bound & m) == 0L) // power of two + r &= m; + else { // reject over-represented candidates + for (long u = r >>> 1; + u + m - (r = u % bound) < 0L; + u = mix64(nextSeed()) >>> 1) + ; + } + return r; + } + + /** + * Returns a pseudorandom {@code long} value between the specified + * origin (inclusive) and the specified bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code long} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public long nextLong(long origin, long bound) { + if (origin >= bound) + throw new IllegalArgumentException(BadRange); + return internalNextLong(origin, bound); + } + + /** + * Returns a pseudorandom {@code double} value between zero + * (inclusive) and one (exclusive). + * + * @return a pseudorandom {@code double} value between zero + * (inclusive) and one (exclusive) + */ + public double nextDouble() { + return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT; + } + + /** + * Returns a pseudorandom {@code double} value between 0.0 + * (inclusive) and the specified bound (exclusive). + * + * @param bound the upper bound (exclusive). Must be positive. + * @return a pseudorandom {@code double} value between zero + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code bound} is not positive + */ + public double nextDouble(double bound) { + if (!(bound > 0.0)) + throw new IllegalArgumentException(BadBound); + double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound; + return (result < bound) ? result : // correct for rounding + Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + } + + /** + * Returns a pseudorandom {@code double} value between the specified + * origin (inclusive) and bound (exclusive). + * + * @param origin the least value returned + * @param bound the upper bound (exclusive) + * @return a pseudorandom {@code double} value between the origin + * (inclusive) and the bound (exclusive) + * @throws IllegalArgumentException if {@code origin} is greater than + * or equal to {@code bound} + */ + public double nextDouble(double origin, double bound) { + if (!(origin < bound)) + throw new IllegalArgumentException(BadRange); + return internalNextDouble(origin, bound); + } + + /** + * Returns a pseudorandom {@code boolean} value. + * + * @return a pseudorandom {@code boolean} value + */ + public boolean nextBoolean() { + return mix32(nextSeed()) < 0; + } + + // stream methods, coded in a way intended to better isolate for + // maintenance purposes the small differences across forms. + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code int} values from this generator and/or + * one split from it. + * + * @param streamSize the number of values to generate + * @return a stream of pseudorandom {@code int} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public IntStream ints(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, streamSize, Integer.MAX_VALUE, 0), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code int} + * values from this generator and/or one split from it. + * + * @implNote This method is implemented to be equivalent to {@code + * ints(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code int} values + */ + public IntStream ints() { + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code int} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code int} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero, or {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public IntStream ints(long streamSize, int randomNumberOrigin, + int randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * int} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code int} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public IntStream ints(int randomNumberOrigin, int randomNumberBound) { + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.intStream + (new RandomIntsSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number + * of pseudorandom {@code long} values from this generator and/or + * one split from it. + * + * @param streamSize the number of values to generate + * @return a stream of pseudorandom {@code long} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public LongStream longs(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, streamSize, Long.MAX_VALUE, 0L), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * long} values from this generator and/or one split from it. + * + * @implNote This method is implemented to be equivalent to {@code + * longs(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code long} values + */ + public LongStream longs() { + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code long} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code long} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero, or {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public LongStream longs(long streamSize, long randomNumberOrigin, + long randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * long} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code long} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public LongStream longs(long randomNumberOrigin, long randomNumberBound) { + if (randomNumberOrigin >= randomNumberBound) + throw new IllegalArgumentException(BadRange); + return StreamSupport.longStream + (new RandomLongsSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code double} values from this generator and/or one split + * from it; each value is between zero (inclusive) and one (exclusive). + * + * @param streamSize the number of values to generate + * @return a stream of {@code double} values + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + */ + public DoubleStream doubles(long streamSize) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, streamSize, Double.MAX_VALUE, 0.0), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * double} values from this generator and/or one split from it; each value + * is between zero (inclusive) and one (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * doubles(Long.MAX_VALUE)}. + * + * @return a stream of pseudorandom {@code double} values + */ + public DoubleStream doubles() { + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0), + false); + } + + /** + * Returns a stream producing the given {@code streamSize} number of + * pseudorandom {@code double} values from this generator and/or one split + * from it; each value conforms to the given origin (inclusive) and bound + * (exclusive). + * + * @param streamSize the number of values to generate + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code double} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code streamSize} is + * less than zero + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public DoubleStream doubles(long streamSize, double randomNumberOrigin, + double randomNumberBound) { + if (streamSize < 0L) + throw new IllegalArgumentException(BadSize); + if (!(randomNumberOrigin < randomNumberBound)) + throw new IllegalArgumentException(BadRange); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, streamSize, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Returns an effectively unlimited stream of pseudorandom {@code + * double} values from this generator and/or one split from it; each value + * conforms to the given origin (inclusive) and bound (exclusive). + * + * @implNote This method is implemented to be equivalent to {@code + * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}. + * + * @param randomNumberOrigin the origin (inclusive) of each random value + * @param randomNumberBound the bound (exclusive) of each random value + * @return a stream of pseudorandom {@code double} values, + * each with the given origin (inclusive) and bound (exclusive) + * @throws IllegalArgumentException if {@code randomNumberOrigin} + * is greater than or equal to {@code randomNumberBound} + */ + public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) { + if (!(randomNumberOrigin < randomNumberBound)) + throw new IllegalArgumentException(BadRange); + return StreamSupport.doubleStream + (new RandomDoublesSpliterator + (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound), + false); + } + + /** + * Spliterator for int streams. We multiplex the four int + * versions into one class by treating a bound less than origin as + * unbounded, and also by treating "infinite" as equivalent to + * Long.MAX_VALUE. For splits, it uses the standard divide-by-two + * approach. The long and double versions of this class are + * identical except for types. + */ + static final class RandomIntsSpliterator implements Spliterator.OfInt { + final SplittableRandom rng; + long index; + final long fence; + final int origin; + final int bound; + RandomIntsSpliterator(SplittableRandom rng, long index, long fence, + int origin, int bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomIntsSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(IntConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextInt(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(IntConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + int o = origin, b = bound; + do { + consumer.accept(r.internalNextInt(o, b)); + } while (++i < f); + } + } + } + + /** + * Spliterator for long streams. + */ + static final class RandomLongsSpliterator implements Spliterator.OfLong { + final SplittableRandom rng; + long index; + final long fence; + final long origin; + final long bound; + RandomLongsSpliterator(SplittableRandom rng, long index, long fence, + long origin, long bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomLongsSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(LongConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextLong(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(LongConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + long o = origin, b = bound; + do { + consumer.accept(r.internalNextLong(o, b)); + } while (++i < f); + } + } + + } + + /** + * Spliterator for double streams. + */ + static final class RandomDoublesSpliterator implements Spliterator.OfDouble { + final SplittableRandom rng; + long index; + final long fence; + final double origin; + final double bound; + RandomDoublesSpliterator(SplittableRandom rng, long index, long fence, + double origin, double bound) { + this.rng = rng; this.index = index; this.fence = fence; + this.origin = origin; this.bound = bound; + } + + public RandomDoublesSpliterator trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + public boolean tryAdvance(DoubleConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rng.internalNextDouble(origin, bound)); + index = i + 1; + return true; + } + return false; + } + + public void forEachRemaining(DoubleConsumer consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + index = f; + SplittableRandom r = rng; + double o = origin, b = bound; + do { + consumer.accept(r.internalNextDouble(o, b)); + } while (++i < f); + } + } + } + +}
--- a/src/share/classes/java/util/TimSort.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/TimSort.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,4 +1,5 @@ /* + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009 Google Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -176,7 +177,7 @@ */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; }
--- a/src/share/classes/java/util/TreeMap.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/TreeMap.java Tue Aug 27 12:27:31 2013 -0400 @@ -790,8 +790,19 @@ /** * Returns a {@link Set} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are + * + * <p>The set's iterator returns the keys in ascending order. + * The set's spliterator is + * <em><a href="Spliterator.html#binding">late-binding</a></em>, + * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} + * and {@link Spliterator#ORDERED} with an encounter order that is ascending + * key order. The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the tree map's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the tree map's comparator. + * + * <p>The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own {@code remove} operation), the results of @@ -823,9 +834,15 @@ /** * Returns a {@link Collection} view of the values contained in this map. - * The collection's iterator returns the values in ascending order - * of the corresponding keys. - * The collection is backed by the map, so changes to the map are + * + * <p>The collection's iterator returns the values in ascending order + * of the corresponding keys. The collection's spliterator is + * <em><a href="Spliterator.html#binding">late-binding</a></em>, + * <em>fail-fast</em>, and additionally reports {@link Spliterator#ORDERED} + * with an encounter order that is ascending order of the corresponding + * keys. + * + * <p>The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. If the map is * modified while an iteration over the collection is in progress * (except through the iterator's own {@code remove} operation), @@ -843,8 +860,15 @@ /** * Returns a {@link Set} view of the mappings contained in this map. - * The set's iterator returns the entries in ascending key order. - * The set is backed by the map, so changes to the map are + * + * <p>The set's iterator returns the entries in ascending key order. The + * sets's spliterator is + * <em><a href="Spliterator.html#binding">late-binding</a></em>, + * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED} with an encounter order that is ascending key + * order. + * + * <p>The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own {@code remove} operation, or through the @@ -949,6 +973,27 @@ } @Override + public boolean replace(K key, V oldValue, V newValue) { + Entry<K,V> p = getEntry(key); + if (p!=null && Objects.equals(oldValue, p.value)) { + p.value = newValue; + return true; + } + return false; + } + + @Override + public V replace(K key, V value) { + Entry<K,V> p = getEntry(key); + if (p!=null) { + V oldValue = p.value; + p.value = value; + return oldValue; + } + return null; + } + + @Override public void forEach(BiConsumer<? super K, ? super V> action) { Objects.requireNonNull(action); int expectedModCount = modCount;
--- a/src/share/classes/java/util/TreeSet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/TreeSet.java Tue Aug 27 12:27:31 2013 -0400 @@ -533,6 +533,25 @@ tm.readTreeSet(size, s, PRESENT); } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * set. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED}, and + * {@link Spliterator#ORDERED}. Overriding implementations should document + * the reporting of additional characteristic values. + * + * <p>The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the tree set's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the tree set's comparator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator<E> spliterator() { return TreeMap.keySpliteratorFor(m); }
--- a/src/share/classes/java/util/Vector.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/Vector.java Tue Aug 27 12:27:31 2013 -0400 @@ -1323,6 +1323,19 @@ modCount++; } + /** + * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em> + * and <em>fail-fast</em> {@link Spliterator} over the elements in this + * list. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED}, + * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}. + * Overriding implementations should document the reporting of additional + * characteristic values. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ @Override public Spliterator<E> spliterator() { return new VectorSpliterator<>(this, null, 0, -1, 0);
--- a/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ArrayBlockingQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -757,12 +757,8 @@ * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue in proper sequence */ @@ -1396,9 +1392,26 @@ // } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator<E> spliterator() { return Spliterators.spliterator (this, Spliterator.ORDERED | Spliterator.NONNULL | Spliterator.CONCURRENT); } + }
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Aug 27 12:27:31 2013 -0400 @@ -43,7 +43,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Comparator; -import java.util.ConcurrentModificationException; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; @@ -94,14 +93,14 @@ * that key reporting the updated value.) For aggregate operations * such as {@code putAll} and {@code clear}, concurrent retrievals may * reflect insertion or removal of only some entries. Similarly, - * Iterators and Enumerations return elements reflecting the state of - * the hash table at some point at or since the creation of the + * Iterators, Spliterators and Enumerations return elements reflecting the + * state of the hash table at some point at or since the creation of the * iterator/enumeration. They do <em>not</em> throw {@link - * ConcurrentModificationException}. However, iterators are designed - * to be used by only one thread at a time. Bear in mind that the - * results of aggregate status methods including {@code size}, {@code - * isEmpty}, and {@code containsValue} are typically useful only when - * a map is not undergoing concurrent updates in other threads. + * java.util.ConcurrentModificationException ConcurrentModificationException}. + * However, iterators are designed to be used by only one thread at a time. + * Bear in mind that the results of aggregate status methods including + * {@code size}, {@code isEmpty}, and {@code containsValue} are typically + * useful only when a map is not undergoing concurrent updates in other threads. * Otherwise the results of these methods reflect transient states * that may be adequate for monitoring or estimation purposes, but not * for program control. @@ -1200,11 +1199,11 @@ * operations. It does not support the {@code add} or * {@code addAll} operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. * * @return the set view */ @@ -1223,11 +1222,11 @@ * {@code retainAll}, and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT} + * and {@link Spliterator#NONNULL}. * * @return the collection view */ @@ -1245,11 +1244,11 @@ * {@code removeAll}, {@code retainAll}, and {@code clear} * operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}. * * @return the set view */ @@ -4308,12 +4307,12 @@ // implementations below rely on concrete classes supplying these // abstract methods /** - * Returns a "weakly consistent" iterator that will never - * throw {@link ConcurrentModificationException}, and - * guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to - * construction. + * Returns an iterator over the elements in this collection. + * + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * @return an iterator over the elements in this collection */ public abstract Iterator<E> iterator(); public abstract boolean contains(Object o);
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Tue Aug 27 12:27:31 2013 -0400 @@ -55,12 +55,8 @@ * Like most other concurrent collection implementations, this class * does not permit the use of {@code null} elements. * - * <p>Iterators are <i>weakly consistent</i>, returning elements - * reflecting the state of the deque at some point at or since the - * creation of the iterator. They do <em>not</em> throw {@link - * java.util.ConcurrentModificationException - * ConcurrentModificationException}, and may proceed concurrently with - * other operations. + * <p>Iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * <p>Beware that, unlike in most collections, the {@code size} method * is <em>NOT</em> a constant-time operation. Because of the @@ -1290,12 +1286,8 @@ * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this deque in proper sequence */ @@ -1308,12 +1300,8 @@ * sequential order. The elements will be returned in order from * last (tail) to first (head). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this deque in reverse order */ @@ -1493,6 +1481,22 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this deque. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator<E> spliterator() { return new CLDSpliterator<E>(this); } @@ -1500,6 +1504,8 @@ /** * Saves this deque to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -1522,6 +1528,10 @@ /** * Reconstitutes this deque from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
--- a/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -654,12 +654,8 @@ * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue in proper sequence */ @@ -749,6 +745,8 @@ /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -771,6 +769,10 @@ /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -881,6 +883,23 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ + @Override public Spliterator<E> spliterator() { return new CLQSpliterator<E>(this); }
--- a/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentNavigableMap.java Tue Aug 27 12:27:31 2013 -0400 @@ -120,11 +120,8 @@ * operations. It does not support the {@code add} or {@code addAll} * operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return a navigable set view of the keys in this map */ @@ -141,11 +138,8 @@ * operations. It does not support the {@code add} or {@code addAll} * operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * <p>This method is equivalent to method {@code navigableKeySet}. * @@ -164,11 +158,8 @@ * operations. It does not support the {@code add} or {@code addAll} * operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator - * that will never throw {@link ConcurrentModificationException}, - * and guarantees to traverse elements as they existed upon - * construction of the iterator, and may (but is not guaranteed to) - * reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return a reverse order navigable set view of the keys in this map */
--- a/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Tue Aug 27 12:27:31 2013 -0400 @@ -71,12 +71,13 @@ * {@code containsKey}, {@code get}, {@code put} and * {@code remove} operations and their variants. Insertion, removal, * update, and access operations safely execute concurrently by - * multiple threads. Iterators are <i>weakly consistent</i>, returning - * elements reflecting the state of the map at some point at or since - * the creation of the iterator. They do <em>not</em> throw {@link - * java.util.ConcurrentModificationException ConcurrentModificationException}, - * and may proceed concurrently with other operations. Ascending key ordered - * views and their iterators are faster than descending ones. + * multiple threads. + * + * <p>Iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>Ascending key ordered views and their iterators are faster than + * descending ones. * * <p>All {@code Map.Entry} pairs returned by methods in this class * and its views represent snapshots of mappings at the time they were @@ -1804,8 +1805,18 @@ /** * Returns a {@link NavigableSet} view of the keys contained in this map. - * The set's iterator returns the keys in ascending order. - * The set is backed by the map, so changes to the map are + * + * <p>The set's iterator returns the keys in ascending order. + * The set's spliterator additionally reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * key order. The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the map's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the map's comparator. + * + * <p>The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. The set supports element * removal, which removes the corresponding mapping from the map, * via the {@code Iterator.remove}, {@code Set.remove}, @@ -1813,11 +1824,8 @@ * operations. It does not support the {@code add} or {@code addAll} * operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * <p>This method is equivalent to method {@code navigableKeySet}. * @@ -1835,9 +1843,13 @@ /** * Returns a {@link Collection} view of the values contained in this map. - * The collection's iterator returns the values in ascending order - * of the corresponding keys. - * The collection is backed by the map, so changes to the map are + * <p>The collection's iterator returns the values in ascending order + * of the corresponding keys. The collections's spliterator additionally + * reports {@link Spliterator#CONCURRENT}, {@link Spliterator#NONNULL} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * order of the corresponding keys. + * + * <p>The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. The collection * supports element removal, which removes the corresponding * mapping from the map, via the {@code Iterator.remove}, @@ -1845,11 +1857,8 @@ * {@code retainAll} and {@code clear} operations. It does not * support the {@code add} or {@code addAll} operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. */ public Collection<V> values() { Values<V> vs = values; @@ -1858,8 +1867,14 @@ /** * Returns a {@link Set} view of the mappings contained in this map. - * The set's iterator returns the entries in ascending key order. - * The set is backed by the map, so changes to the map are + * + * <p>The set's iterator returns the entries in ascending key order. The + * set's spliterator additionally reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#SORTED} and + * {@link Spliterator#ORDERED}, with an encounter order that is ascending + * key order. + * + * <p>The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. The set supports element * removal, which removes the corresponding mapping from the map, * via the {@code Iterator.remove}, {@code Set.remove}, @@ -1867,15 +1882,12 @@ * operations. It does not support the {@code add} or * {@code addAll} operations. * - * <p>The view's {@code iterator} is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse elements - * as they existed upon construction of the iterator, and may (but is not - * guaranteed to) reflect any modifications subsequent to construction. + * <p>The view's iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * - * <p>The {@code Map.Entry} elements returned by - * {@code iterator.next()} do <em>not</em> support the - * {@code setValue} operation. + * <p>The {@code Map.Entry} elements traversed by the {@code iterator} + * or {@code spliterator} do <em>not</em> support the {@code setValue} + * operation. * * @return a set view of the mappings contained in this map, * sorted in ascending key order
--- a/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Tue Aug 27 12:27:31 2013 -0400 @@ -57,12 +57,12 @@ * cost for the {@code contains}, {@code add}, and {@code remove} * operations and their variants. Insertion, removal, and access * operations safely execute concurrently by multiple threads. - * Iterators are <i>weakly consistent</i>, returning elements - * reflecting the state of the set at some point at or since the - * creation of the iterator. They do <em>not</em> throw {@link - * java.util.ConcurrentModificationException}, and may proceed - * concurrently with other operations. Ascending ordered views and - * their iterators are faster than descending ones. + * + * <p>Iterators and spliterators are + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>Ascending ordered views and their iterators are faster than + * descending ones. * * <p>Beware that, unlike in most collections, the {@code size} * method is <em>not</em> a constant-time operation. Because of the @@ -480,6 +480,24 @@ return new ConcurrentSkipListSet<E>(m.descendingMap()); } + /** + * Returns a {@link Spliterator} over the elements in this set. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#NONNULL}, {@link Spliterator#DISTINCT}, + * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}, with an + * encounter order that is ascending order. Overriding implementations + * should document the reporting of additional characteristic values. + * + * <p>The spliterator's comparator (see + * {@link java.util.Spliterator#getComparator()}) is {@code null} if + * the set's comparator (see {@link #comparator()}) is {@code null}. + * Otherwise, the spliterator's comparator is the same as or imposes the + * same total ordering as the set's comparator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ @SuppressWarnings("unchecked") public Spliterator<E> spliterator() { if (m instanceof ConcurrentSkipListMap)
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Tue Aug 27 12:27:31 2013 -0400 @@ -952,6 +952,8 @@ /** * Saves this list to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The length of the array backing the list is emitted * (int), followed by all of its elements (each an Object) * in the proper order. @@ -972,6 +974,10 @@ /** * Reconstitutes this list from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -1092,15 +1098,29 @@ * * @throws IndexOutOfBoundsException {@inheritDoc} */ - public ListIterator<E> listIterator(final int index) { + public ListIterator<E> listIterator(int index) { Object[] elements = getArray(); int len = elements.length; - if (index<0 || index>len) + if (index < 0 || index > len) throw new IndexOutOfBoundsException("Index: "+index); return new COWIterator<E>(elements, index); } + /** + * Returns a {@link Spliterator} over the elements in this list. + * + * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE}, + * {@link Spliterator#ORDERED}, {@link Spliterator#SIZED}, and + * {@link Spliterator#SUBSIZED}. + * + * <p>The spliterator provides a snapshot of the state of the list + * when the spliterator was constructed. No synchronization is needed while + * operating on the spliterator. + * + * @return a {@code Spliterator} over the elements in this list + * @since 1.8 + */ public Spliterator<E> spliterator() { return Spliterators.spliterator (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED); @@ -1257,7 +1277,7 @@ // only call this holding l's lock private void rangeCheck(int index) { - if (index<0 || index>=size) + if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ",Size: "+size); } @@ -1304,7 +1324,7 @@ lock.lock(); try { checkForComodification(); - if (index<0 || index>size) + if (index < 0 || index > size) throw new IndexOutOfBoundsException(); l.add(index+offset, element); expectedArray = l.getArray(); @@ -1361,12 +1381,12 @@ } } - public ListIterator<E> listIterator(final int index) { + public ListIterator<E> listIterator(int index) { final ReentrantLock lock = l.lock; lock.lock(); try { checkForComodification(); - if (index<0 || index>size) + if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); return new COWSubListIterator<E>(l, index, offset, size); @@ -1380,7 +1400,7 @@ lock.lock(); try { checkForComodification(); - if (fromIndex<0 || toIndex>size) + if (fromIndex < 0 || toIndex > size) throw new IndexOutOfBoundsException(); return new COWSubList<E>(l, fromIndex + offset, toIndex + offset); @@ -1580,6 +1600,7 @@ return Spliterators.spliterator (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED); } + } private static class COWSubListIterator<E> implements ListIterator<E> {
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/CopyOnWriteArraySet.java Tue Aug 27 12:27:31 2013 -0400 @@ -404,6 +404,21 @@ al.forEach(action); } + /** + * Returns a {@link Spliterator} over the elements in this set in the order + * in which these elements were added. + * + * <p>The {@code Spliterator} reports {@link Spliterator#IMMUTABLE}, + * {@link Spliterator#DISTINCT}, {@link Spliterator#SIZED}, and + * {@link Spliterator#SUBSIZED}. + * + * <p>The spliterator provides a snapshot of the state of the set + * when the spliterator was constructed. No synchronization is needed while + * operating on the spliterator. + * + * @return a {@code Spliterator} over the elements in this set + * @since 1.8 + */ public Spliterator<E> spliterator() { return Spliterators.spliterator (al.getArray(), Spliterator.IMMUTABLE | Spliterator.DISTINCT);
--- a/src/share/classes/java/util/concurrent/DelayQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/DelayQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -512,12 +512,8 @@ * unexpired) in this queue. The iterator does not return the * elements in any particular order. * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue */
--- a/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java Tue Aug 27 12:27:31 2013 -0400 @@ -1008,12 +1008,8 @@ * Returns an iterator over the elements in this deque in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this deque in proper sequence */ @@ -1026,12 +1022,8 @@ * sequential order. The elements will be returned in order from * last (tail) to first (head). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this deque in reverse order */ @@ -1270,6 +1262,22 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this deque. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this deque + * @since 1.8 + */ public Spliterator<E> spliterator() { return new LBDSpliterator<E>(this); } @@ -1277,6 +1285,8 @@ /** * Saves this deque to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The capacity (int), followed by elements (each an * {@code Object}) in the proper order, followed by a null */ @@ -1299,6 +1309,10 @@ /** * Reconstitutes this deque from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
--- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -766,12 +766,8 @@ * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue in proper sequence */ @@ -973,6 +969,22 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator<E> spliterator() { return new LBQSpliterator<E>(this); } @@ -980,6 +992,8 @@ /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData The capacity is emitted (int), followed by all of * its elements (each an {@code Object}) in the proper order, * followed by a null @@ -1005,6 +1019,10 @@ /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
--- a/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/LinkedTransferQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -40,6 +40,7 @@ import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; import java.util.Spliterator; import java.util.Spliterators; @@ -1018,6 +1019,22 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#CONCURRENT}, + * {@link Spliterator#ORDERED}, and {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} implements {@code trySplit} to permit limited + * parallelism. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator<E> spliterator() { return new LTQSpliterator<E>(this); } @@ -1301,12 +1318,8 @@ * Returns an iterator over the elements in this queue in proper sequence. * The elements will be returned in order from first (head) to last (tail). * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue in proper sequence */ @@ -1407,6 +1420,8 @@ /** * Saves this queue to a stream (that is, serializes it). * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData All of the elements (each an {@code E}) in * the proper order, followed by a null */ @@ -1421,6 +1436,10 @@ /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
--- a/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -229,7 +229,7 @@ /** * Creates a {@code PriorityBlockingQueue} containing the elements * in the specified collection. If the specified collection is a - * {@link SortedSet} or a {@link PriorityQueue}, this + * {@link SortedSet} or a {@link PriorityQueue}, this * priority queue will be ordered according to the same ordering. * Otherwise, this priority queue will be ordered according to the * {@linkplain Comparable natural ordering} of its elements. @@ -864,12 +864,8 @@ * Returns an iterator over the elements in this queue. The * iterator does not return the elements in any particular order. * - * <p>The returned iterator is a "weakly consistent" iterator that - * will never throw {@link java.util.ConcurrentModificationException - * ConcurrentModificationException}, and guarantees to traverse - * elements as they existed upon construction of the iterator, and - * may (but is not guaranteed to) reflect any modifications - * subsequent to construction. + * <p>The returned iterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. * * @return an iterator over the elements in this queue */ @@ -915,6 +911,9 @@ * For compatibility with previous version of this class, elements * are first copied to a java.util.PriorityQueue, which is then * serialized. + * + * @param s the stream + * @throws java.io.IOException if an I/O error occurs */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { @@ -932,6 +931,10 @@ /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -1005,6 +1008,21 @@ } } + /** + * Returns a {@link Spliterator} over the elements in this queue. + * + * <p>The returned spliterator is + * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>. + * + * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and + * {@link Spliterator#NONNULL}. + * + * @implNote + * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}. + * + * @return a {@code Spliterator} over the elements in this queue + * @since 1.8 + */ public Spliterator<E> spliterator() { return new PBQSpliterator<E>(this, null, 0, -1); }
--- a/src/share/classes/java/util/concurrent/SynchronousQueue.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/SynchronousQueue.java Tue Aug 27 12:27:31 2013 -0400 @@ -38,6 +38,8 @@ import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.ReentrantLock; import java.util.*; +import java.util.Spliterator; +import java.util.Spliterators; /** * A {@linkplain BlockingQueue blocking queue} in which each insert @@ -1062,21 +1064,17 @@ * * @return an empty iterator */ - @SuppressWarnings("unchecked") public Iterator<E> iterator() { - return (Iterator<E>) EmptyIterator.EMPTY_ITERATOR; + return Collections.emptyIterator(); } - // Replicated from a previous version of Collections - private static class EmptyIterator<E> implements Iterator<E> { - static final EmptyIterator<Object> EMPTY_ITERATOR - = new EmptyIterator<Object>(); - - public boolean hasNext() { return false; } - public E next() { throw new NoSuchElementException(); } - public void remove() { throw new IllegalStateException(); } - } - + /** + * Returns an empty spliterator in which calls to + * {@link java.util.Spliterator#trySplit()} always return {@code null}. + * + * @return an empty spliterator + * @since 1.8 + */ public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); } @@ -1163,6 +1161,8 @@ /** * Saves this queue to a stream (that is, serializes it). + * @param s the stream + * @throws java.io.IOException if an I/O error occurs */ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { @@ -1182,8 +1182,12 @@ /** * Reconstitutes this queue from a stream (that is, deserializes it). + * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ - private void readObject(final java.io.ObjectInputStream s) + private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); if (waitingProducers instanceof FifoWaitQueue)
--- a/src/share/classes/java/util/concurrent/locks/StampedLock.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/locks/StampedLock.java Tue Aug 27 12:27:31 2013 -0400 @@ -226,7 +226,11 @@ * incoming reader arrives while read lock is held but there is a * queued writer, this incoming reader is queued. (This rule is * responsible for some of the complexity of method acquireRead, - * but without it, the lock becomes highly unfair.) + * but without it, the lock becomes highly unfair.) Method release + * does not (and sometimes cannot) itself wake up cowaiters. This + * is done by the primary thread, but helped by any other threads + * with nothing better to do in methods acquireRead and + * acquireWrite. * * These rules apply to threads actually queued. All tryLock forms * opportunistically try to acquire locks regardless of preference @@ -267,11 +271,14 @@ /** Number of processors, for spin control */ private static final int NCPU = Runtime.getRuntime().availableProcessors(); - /** Maximum number of retries before blocking on acquisition */ + /** Maximum number of retries before enqueuing on acquisition */ private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0; + /** Maximum number of retries before blocking at head on acquisition */ + private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0; + /** Maximum number of retries before re-blocking */ - private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0; + private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0; /** The period for yielding when waiting for overflow spinlock */ private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1 @@ -415,8 +422,8 @@ * @return a stamp that can be used to unlock or convert mode */ public long readLock() { - long s, next; // bypass acquireRead on fully unlocked case only - return ((((s = state) & ABITS) == 0L && + long s = state, next; // bypass acquireRead on common uncontended case + return ((whead == wtail && (s & ABITS) < RFULL && U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ? next : acquireRead(false, 0L)); } @@ -1012,17 +1019,8 @@ if (t.status <= 0) q = t; } - if (q != null) { - for (WNode r = q;;) { // release co-waiters too - if ((w = r.thread) != null) { - r.thread = null; - U.unpark(w); - } - if ((r = q.cowait) == null) - break; - U.compareAndSwapObject(q, WCOWAIT, r, r.cowait); - } - } + if (q != null && (w = q.thread) != null) + U.unpark(w); } } @@ -1038,22 +1036,22 @@ private long acquireWrite(boolean interruptible, long deadline) { WNode node = null, p; for (int spins = -1;;) { // spin while enqueuing - long s, ns; - if (((s = state) & ABITS) == 0L) { + long m, s, ns; + if ((m = (s = state) & ABITS) == 0L) { if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT)) return ns; } + else if (spins < 0) + spins = (m == WBIT && wtail == whead) ? SPINS : 0; else if (spins > 0) { if (LockSupport.nextSecondarySeed() >= 0) --spins; } else if ((p = wtail) == null) { // initialize queue - WNode h = new WNode(WMODE, null); - if (U.compareAndSwapObject(this, WHEAD, null, h)) - wtail = h; + WNode hd = new WNode(WMODE, null); + if (U.compareAndSwapObject(this, WHEAD, null, hd)) + wtail = hd; } - else if (spins < 0) - spins = (p == whead) ? SPINS : 0; else if (node == null) node = new WNode(WMODE, p); else if (node.prev != p) @@ -1064,14 +1062,18 @@ } } - for (int spins = SPINS;;) { - WNode np, pp; int ps; long s, ns; Thread w; - while ((np = node.prev) != p && np != null) - (p = np).next = node; // stale - if (whead == p) { + for (int spins = -1;;) { + WNode h, np, pp; int ps; + if ((h = whead) == p) { + if (spins < 0) + spins = HEAD_SPINS; + else if (spins < MAX_HEAD_SPINS) + spins <<= 1; for (int k = spins;;) { // spin at head + long s, ns; if (((s = state) & ABITS) == 0L) { - if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) { + if (U.compareAndSwapLong(this, STATE, s, + ns = s + WBIT)) { whead = node; node.prev = null; return ns; @@ -1081,33 +1083,45 @@ --k <= 0) break; } - if (spins < MAX_HEAD_SPINS) - spins <<= 1; } - if ((ps = p.status) == 0) - U.compareAndSwapInt(p, WSTATUS, 0, WAITING); - else if (ps == CANCELLED) { - if ((pp = p.prev) != null) { - node.prev = pp; - pp.next = node; + else if (h != null) { // help release stale waiters + WNode c; Thread w; + while ((c = h.cowait) != null) { + if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } } - else { - long time; // 0 argument to park means no timeout - if (deadline == 0L) - time = 0L; - else if ((time = deadline - System.nanoTime()) <= 0L) - return cancelWaiter(node, node, false); - Thread wt = Thread.currentThread(); - U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport.park - node.thread = wt; - if (node.prev == p && p.status == WAITING && // recheck - (p != whead || (state & ABITS) != 0L)) - U.park(false, time); - node.thread = null; - U.putObject(wt, PARKBLOCKER, null); - if (interruptible && Thread.interrupted()) - return cancelWaiter(node, node, true); + if (whead == h) { + if ((np = node.prev) != p) { + if (np != null) + (p = np).next = node; // stale + } + else if ((ps = p.status) == 0) + U.compareAndSwapInt(p, WSTATUS, 0, WAITING); + else if (ps == CANCELLED) { + if ((pp = p.prev) != null) { + node.prev = pp; + pp.next = node; + } + } + else { + long time; // 0 argument to park means no timeout + if (deadline == 0L) + time = 0L; + else if ((time = deadline - System.nanoTime()) <= 0L) + return cancelWaiter(node, node, false); + Thread wt = Thread.currentThread(); + U.putObject(wt, PARKBLOCKER, this); + node.thread = wt; + if (p.status < 0 && (p != h || (state & ABITS) != 0L) && + whead == h && node.prev == p) + U.park(false, time); // emulate LockSupport.park + node.thread = null; + U.putObject(wt, PARKBLOCKER, null); + if (interruptible && Thread.interrupted()) + return cancelWaiter(node, node, true); + } } } } @@ -1122,138 +1136,159 @@ * @return next state, or INTERRUPTED */ private long acquireRead(boolean interruptible, long deadline) { - WNode node = null, group = null, p; + WNode node = null, p; for (int spins = -1;;) { - for (;;) { - long s, m, ns; WNode h, q; Thread w; // anti-barging guard - if (group == null && (h = whead) != null && - (q = h.next) != null && q.mode != RMODE) - break; - if ((m = (s = state) & ABITS) < RFULL ? - U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : - (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) { - if (group != null) { // help release others - for (WNode r = group;;) { - if ((w = r.thread) != null) { - r.thread = null; - U.unpark(w); + WNode h; + if ((h = whead) == (p = wtail)) { + for (long m, s, ns;;) { + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : + (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) + return ns; + else if (m >= WBIT) { + if (spins > 0) { + if (LockSupport.nextSecondarySeed() >= 0) + --spins; + } + else { + if (spins == 0) { + WNode nh = whead, np = wtail; + if ((nh == h && np == p) || (h = nh) != (p = np)) + break; } - if ((r = group.cowait) == null) - break; - U.compareAndSwapObject(group, WCOWAIT, r, r.cowait); + spins = SPINS; } } - return ns; } - if (m >= WBIT) - break; + } + if (p == null) { // initialize queue + WNode hd = new WNode(WMODE, null); + if (U.compareAndSwapObject(this, WHEAD, null, hd)) + wtail = hd; } - if (spins > 0) { - if (LockSupport.nextSecondarySeed() >= 0) - --spins; - } - else if ((p = wtail) == null) { - WNode h = new WNode(WMODE, null); - if (U.compareAndSwapObject(this, WHEAD, null, h)) - wtail = h; + else if (node == null) + node = new WNode(RMODE, p); + else if (h == p || p.mode != RMODE) { + if (node.prev != p) + node.prev = p; + else if (U.compareAndSwapObject(this, WTAIL, p, node)) { + p.next = node; + break; + } } - else if (spins < 0) - spins = (p == whead) ? SPINS : 0; - else if (node == null) - node = new WNode(WMODE, p); - else if (node.prev != p) - node.prev = p; - else if (p.mode == RMODE && p != whead) { - WNode pp = p.prev; // become co-waiter with group p - if (pp != null && p == wtail && - U.compareAndSwapObject(p, WCOWAIT, - node.cowait = p.cowait, node)) { - node.thread = Thread.currentThread(); - for (long time;;) { + else if (!U.compareAndSwapObject(p, WCOWAIT, + node.cowait = p.cowait, node)) + node.cowait = null; + else { + for (;;) { + WNode pp, c; Thread w; + if ((h = whead) != null && (c = h.cowait) != null && + U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) // help release + U.unpark(w); + if (h == (pp = p.prev) || h == p || pp == null) { + long m, s, ns; + do { + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, + ns = s + RUNIT) : + (m < WBIT && + (ns = tryIncReaderOverflow(s)) != 0L)) + return ns; + } while (m < WBIT); + } + if (whead == h && p.prev == pp) { + long time; + if (pp == null || h == p || p.status > 0) { + node = null; // throw away + break; + } if (deadline == 0L) time = 0L; else if ((time = deadline - System.nanoTime()) <= 0L) return cancelWaiter(node, p, false); - if (node.thread == null) - break; - if (p.prev != pp || p.status == CANCELLED || - p == whead || p.prev != pp) { - node.thread = null; - break; - } Thread wt = Thread.currentThread(); U.putObject(wt, PARKBLOCKER, this); - if (node.thread == null) // must recheck - break; - U.park(false, time); + node.thread = wt; + if ((h != pp || (state & ABITS) == WBIT) && + whead == h && p.prev == pp) + U.park(false, time); + node.thread = null; U.putObject(wt, PARKBLOCKER, null); if (interruptible && Thread.interrupted()) return cancelWaiter(node, p, true); } - group = p; } - node = null; // throw away - } - else if (U.compareAndSwapObject(this, WTAIL, p, node)) { - p.next = node; - break; } } - for (int spins = SPINS;;) { - WNode np, pp, r; int ps; long m, s, ns; Thread w; - while ((np = node.prev) != p && np != null) - (p = np).next = node; - if (whead == p) { - for (int k = spins;;) { - if ((m = (s = state) & ABITS) != WBIT) { - if (m < RFULL ? - U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT): - (ns = tryIncReaderOverflow(s)) != 0L) { - whead = node; - node.prev = null; - while ((r = node.cowait) != null) { - if (U.compareAndSwapObject(node, WCOWAIT, - r, r.cowait) && - (w = r.thread) != null) { - r.thread = null; - U.unpark(w); // release co-waiter - } - } - return ns; + for (int spins = -1;;) { + WNode h, np, pp; int ps; + if ((h = whead) == p) { + if (spins < 0) + spins = HEAD_SPINS; + else if (spins < MAX_HEAD_SPINS) + spins <<= 1; + for (int k = spins;;) { // spin at head + long m, s, ns; + if ((m = (s = state) & ABITS) < RFULL ? + U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) : + (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) { + WNode c; Thread w; + whead = node; + node.prev = null; + while ((c = node.cowait) != null) { + if (U.compareAndSwapObject(node, WCOWAIT, + c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } + return ns; } - else if (LockSupport.nextSecondarySeed() >= 0 && - --k <= 0) + else if (m >= WBIT && + LockSupport.nextSecondarySeed() >= 0 && --k <= 0) break; } - if (spins < MAX_HEAD_SPINS) - spins <<= 1; } - if ((ps = p.status) == 0) - U.compareAndSwapInt(p, WSTATUS, 0, WAITING); - else if (ps == CANCELLED) { - if ((pp = p.prev) != null) { - node.prev = pp; - pp.next = node; + else if (h != null) { + WNode c; Thread w; + while ((c = h.cowait) != null) { + if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) && + (w = c.thread) != null) + U.unpark(w); } } - else { - long time; - if (deadline == 0L) - time = 0L; - else if ((time = deadline - System.nanoTime()) <= 0L) - return cancelWaiter(node, node, false); - Thread wt = Thread.currentThread(); - U.putObject(wt, PARKBLOCKER, this); - node.thread = wt; - if (node.prev == p && p.status == WAITING && - (p != whead || (state & ABITS) != WBIT)) - U.park(false, time); - node.thread = null; - U.putObject(wt, PARKBLOCKER, null); - if (interruptible && Thread.interrupted()) - return cancelWaiter(node, node, true); + if (whead == h) { + if ((np = node.prev) != p) { + if (np != null) + (p = np).next = node; // stale + } + else if ((ps = p.status) == 0) + U.compareAndSwapInt(p, WSTATUS, 0, WAITING); + else if (ps == CANCELLED) { + if ((pp = p.prev) != null) { + node.prev = pp; + pp.next = node; + } + } + else { + long time; + if (deadline == 0L) + time = 0L; + else if ((time = deadline - System.nanoTime()) <= 0L) + return cancelWaiter(node, node, false); + Thread wt = Thread.currentThread(); + U.putObject(wt, PARKBLOCKER, this); + node.thread = wt; + if (p.status < 0 && + (p != h || (state & ABITS) == WBIT) && + whead == h && node.prev == p) + U.park(false, time); + node.thread = null; + U.putObject(wt, PARKBLOCKER, null); + if (interruptible && Thread.interrupted()) + return cancelWaiter(node, node, true); + } } } } @@ -1278,22 +1313,19 @@ if (node != null && group != null) { Thread w; node.status = CANCELLED; - node.thread = null; // unsplice cancelled nodes from group for (WNode p = group, q; (q = p.cowait) != null;) { - if (q.status == CANCELLED) - U.compareAndSwapObject(p, WNEXT, q, q.next); + if (q.status == CANCELLED) { + U.compareAndSwapObject(p, WCOWAIT, q, q.cowait); + p = group; // restart + } else p = q; } if (group == node) { - WNode r; // detach and wake up uncancelled co-waiters - while ((r = node.cowait) != null) { - if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) && - (w = r.thread) != null) { - r.thread = null; - U.unpark(w); - } + for (WNode r = group.cowait; r != null; r = r.cowait) { + if ((w = r.thread) != null) + U.unpark(w); // wake up uncancelled co-waiters } for (WNode pred = node.prev; pred != null; ) { // unsplice WNode succ, pp; // find valid successor
--- a/src/share/classes/java/util/concurrent/package-info.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/concurrent/package-info.java Tue Aug 27 12:27:31 2013 -0400 @@ -210,13 +210,19 @@ * collections are unshared, or are accessible only when * holding other locks. * - * <p>Most concurrent Collection implementations (including most - * Queues) also differ from the usual java.util conventions in that - * their Iterators provide <em>weakly consistent</em> rather than - * fast-fail traversal. A weakly consistent iterator is thread-safe, - * but does not necessarily freeze the collection while iterating, so - * it may (or may not) reflect any updates since the iterator was - * created. + * <p id="Weakly">Most concurrent Collection implementations + * (including most Queues) also differ from the usual {@code java.util} + * conventions in that their {@linkplain java.util.Iterator Iterators} + * and {@linkplain java.util.Spliterator Spliterators} provide + * <em>weakly consistent</em> rather than fast-fail traversal: + * <ul> + * <li>they may proceed concurrently with other operations + * <li>they will never throw {@link java.util.ConcurrentModificationException + * ConcurrentModificationException} + * <li>they are guaranteed to traverse elements as they existed upon + * construction exactly once, and may (but are not guaranteed to) + * reflect any modifications subsequent to construction. + * </ul> * * <h2 id="MemoryVisibility">Memory Consistency Properties</h2> *
--- a/src/share/classes/java/util/jar/JarVerifier.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/jar/JarVerifier.java Tue Aug 27 12:27:31 2013 -0400 @@ -32,6 +32,7 @@ import java.security.cert.CertificateException; import java.util.zip.ZipEntry; +import sun.misc.JarIndex; import sun.security.util.ManifestDigester; import sun.security.util.ManifestEntryVerifier; import sun.security.util.SignatureFileVerifier; @@ -139,7 +140,8 @@ return; } - if (uname.equals(JarFile.MANIFEST_NAME)) { + if (uname.equals(JarFile.MANIFEST_NAME) || + uname.equals(JarIndex.INDEX_NAME)) { return; }
--- a/src/share/classes/java/util/logging/Logger.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/logging/Logger.java Tue Aug 27 12:27:31 2013 -0400 @@ -457,13 +457,15 @@ * of the subsystem, such as java.net * or javax.swing * @param resourceBundleName name of ResourceBundle to be used for localizing - * messages for this logger. May be <CODE>null</CODE> if none of - * the messages require localization. + * messages for this logger. May be {@code null} + * if none of the messages require localization. * @return a suitable Logger * @throws MissingResourceException if the resourceBundleName is non-null and * no corresponding resource can be found. * @throws IllegalArgumentException if the Logger already exists and uses - * a different resource bundle name. + * a different resource bundle name; or if + * {@code resourceBundleName} is {@code null} but the named + * logger has a resource bundle set. * @throws NullPointerException if the name is null. */ @@ -1731,10 +1733,6 @@ // Synchronized to prevent races in setting the fields. private synchronized void setupResourceInfo(String name, Class<?> callersClass) { - if (name == null) { - return; - } - if (resourceBundleName != null) { // this Logger already has a ResourceBundle @@ -1748,6 +1746,10 @@ resourceBundleName + " != " + name); } + if (name == null) { + return; + } + setCallersClassLoaderRef(callersClass); if (findResourceBundle(name, true) == null) { // We've failed to find an expected ResourceBundle.
--- a/src/share/classes/java/util/regex/Pattern.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/regex/Pattern.java Tue Aug 27 12:27:31 2013 -0400 @@ -219,7 +219,7 @@ * * <tr><th> </th></tr> * <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr> - * * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td> + * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td> * <td headers="matches">A Latin script character (<a href="#usc">script</a>)</td></tr> * <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td> * <td headers="matches">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
--- a/src/share/classes/java/util/stream/Collectors.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/Collectors.java Tue Aug 27 12:27:31 2013 -0400 @@ -137,6 +137,11 @@ return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }; } + @SuppressWarnings("unchecked") + private static <I, R> Function<I, R> castingIdentity() { + return i -> (R) i; + } + /** * Simple implementation class for {@code Collector}. * @@ -166,7 +171,7 @@ BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Set<Characteristics> characteristics) { - this(supplier, accumulator, combiner, i -> (R) i, characteristics); + this(supplier, accumulator, combiner, castingIdentity(), characteristics); } @Override @@ -209,7 +214,7 @@ */ public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) { - return new CollectorImpl<>(collectionFactory, Collection::add, + return new CollectorImpl<>(collectionFactory, Collection<T>::add, (r1, r2) -> { r1.addAll(r2); return r1; }, CH_ID); } @@ -1046,30 +1051,23 @@ public static <T, D, A> Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T, A, D> downstream) { - @SuppressWarnings("unchecked") - BiConsumer<D, ? super T> downstreamAccumulator = (BiConsumer<D, ? super T>) downstream.accumulator(); - BiConsumer<Map<Boolean, A>, T> accumulator = (result, t) -> { - Partition<D> asPartition = ((Partition<D>) result); - downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t); - }; + BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator(); + BiConsumer<Partition<A>, T> accumulator = (result, t) -> + downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t); BinaryOperator<A> op = downstream.combiner(); - BinaryOperator<Map<Boolean, A>> merger = (m1, m2) -> { - Partition<A> left = (Partition<A>) m1; - Partition<A> right = (Partition<A>) m2; - return new Partition<>(op.apply(left.forTrue, right.forTrue), - op.apply(left.forFalse, right.forFalse)); - }; - Supplier<Map<Boolean, A>> supplier = () -> new Partition<>(downstream.supplier().get(), - downstream.supplier().get()); + BinaryOperator<Partition<A>> merger = (left, right) -> + new Partition<>(op.apply(left.forTrue, right.forTrue), + op.apply(left.forFalse, right.forFalse)); + Supplier<Partition<A>> supplier = () -> + new Partition<>(downstream.supplier().get(), + downstream.supplier().get()); if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { return new CollectorImpl<>(supplier, accumulator, merger, CH_ID); } else { - Function<Map<Boolean, A>, Map<Boolean, D>> finisher = (Map<Boolean, A> par) -> { - Partition<A> asAPartition = (Partition<A>) par; - return new Partition<>(downstream.finisher().apply(asAPartition.forTrue), - downstream.finisher().apply(asAPartition.forFalse)); - }; + Function<Partition<A>, Map<Boolean, D>> finisher = par -> + new Partition<>(downstream.finisher().apply(par.forTrue), + downstream.finisher().apply(par.forFalse)); return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID); } }
--- a/src/share/classes/java/util/stream/DistinctOps.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/DistinctOps.java Tue Aug 27 12:27:31 2013 -0400 @@ -101,7 +101,7 @@ if (StreamOpFlag.DISTINCT.isKnown(flags)) { return sink; } else if (StreamOpFlag.SORTED.isKnown(flags)) { - return new Sink.ChainedReference<T>(sink) { + return new Sink.ChainedReference<T, T>(sink) { boolean seenNull; T lastSeen; @@ -132,7 +132,7 @@ } }; } else { - return new Sink.ChainedReference<T>(sink) { + return new Sink.ChainedReference<T, T>(sink) { Set<T> seen; @Override
--- a/src/share/classes/java/util/stream/DoublePipeline.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/DoublePipeline.java Tue Aug 27 12:27:31 2013 -0400 @@ -191,7 +191,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Double>(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsDouble(t)); @@ -208,9 +208,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Double> opWrapSink(int flags, Sink<U> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<U>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(double t) { downstream.accept(mapper.apply(t)); } @@ -226,7 +225,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Double> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Integer>(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsInt(t)); @@ -243,7 +242,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Double> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Long>(sink) { @Override public void accept(double t) { downstream.accept(mapper.applyAsLong(t)); @@ -259,7 +258,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Double>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -296,7 +295,7 @@ StreamOpFlag.NOT_SIZED) { @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Double>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -319,7 +318,7 @@ 0) { @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Double>(sink) { @Override public void accept(double t) { consumer.accept(t);
--- a/src/share/classes/java/util/stream/IntPipeline.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/IntPipeline.java Tue Aug 27 12:27:31 2013 -0400 @@ -189,9 +189,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Long>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((long) t); } @@ -206,9 +205,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Double>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept((double) t); } @@ -229,7 +227,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Integer>(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsInt(t)); @@ -246,9 +244,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<U> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<U>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(int t) { downstream.accept(mapper.apply(t)); } @@ -264,7 +261,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Long>(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsLong(t)); @@ -281,7 +278,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Integer> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Double>(sink) { @Override public void accept(int t) { downstream.accept(mapper.applyAsDouble(t)); @@ -297,7 +294,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Integer>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -334,7 +331,7 @@ StreamOpFlag.NOT_SIZED) { @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Integer>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -357,7 +354,7 @@ 0) { @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Integer>(sink) { @Override public void accept(int t) { consumer.accept(t);
--- a/src/share/classes/java/util/stream/LongPipeline.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/LongPipeline.java Tue Aug 27 12:27:31 2013 -0400 @@ -186,7 +186,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Double>(sink) { @Override public void accept(long t) { downstream.accept((double) t); @@ -208,9 +208,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Long>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsLong(t)); } @@ -226,9 +225,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<U> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<U>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.apply(t)); } @@ -244,9 +242,8 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Integer>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(long t) { downstream.accept(mapper.applyAsInt(t)); } @@ -262,7 +259,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<Long> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Double>(sink) { @Override public void accept(long t) { downstream.accept(mapper.applyAsDouble(t)); @@ -278,7 +275,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Long>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -315,7 +312,7 @@ StreamOpFlag.NOT_SIZED) { @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Long>(sink) { @Override public void begin(long size) { downstream.begin(-1); @@ -338,7 +335,7 @@ 0) { @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Long>(sink) { @Override public void accept(long t) { consumer.accept(t);
--- a/src/share/classes/java/util/stream/ReferencePipeline.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/ReferencePipeline.java Tue Aug 27 12:27:31 2013 -0400 @@ -163,17 +163,16 @@ StreamOpFlag.NOT_SIZED) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, P_OUT>(sink) { @Override public void begin(long size) { downstream.begin(-1); } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { if (predicate.test(u)) - downstream.accept((Object) u); + downstream.accept(u); } }; } @@ -188,7 +187,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, R>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.apply(u)); @@ -205,7 +204,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Integer>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsInt(u)); @@ -222,7 +221,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Long>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsLong(u)); @@ -239,7 +238,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Double>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.applyAsDouble(u)); @@ -257,14 +256,13 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, R>(sink) { @Override public void begin(long size) { downstream.begin(-1); } @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { // We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it Stream<? extends R> result = mapper.apply(u); @@ -284,7 +282,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Integer>(sink) { IntConsumer downstreamAsInt = downstream::accept; @Override public void begin(long size) { @@ -311,7 +309,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Double>(sink) { DoubleConsumer downstreamAsDouble = downstream::accept; @Override public void begin(long size) { @@ -338,7 +336,7 @@ StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, Long>(sink) { LongConsumer downstreamAsLong = downstream::accept; @Override public void begin(long size) { @@ -364,9 +362,8 @@ 0) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) { - return new Sink.ChainedReference<P_OUT>(sink) { + return new Sink.ChainedReference<P_OUT, P_OUT>(sink) { @Override - @SuppressWarnings("unchecked") public void accept(P_OUT u) { tee.accept(u); downstream.accept(u); @@ -495,6 +492,7 @@ } @Override + @SuppressWarnings("unchecked") public final <R, A> R collect(Collector<? super P_OUT, A, ? extends R> collector) { A container; if (isParallel()
--- a/src/share/classes/java/util/stream/Sink.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/Sink.java Tue Aug 27 12:27:31 2013 -0400 @@ -241,11 +241,10 @@ * implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedReference<T> implements Sink<T> { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedReference<T, E_OUT> implements Sink<T> { + protected final Sink<? super E_OUT> downstream; - public ChainedReference(Sink downstream) { + public ChainedReference(Sink<? super E_OUT> downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -274,11 +273,10 @@ * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedInt implements Sink.OfInt { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedInt<E_OUT> implements Sink.OfInt { + protected final Sink<? super E_OUT> downstream; - public ChainedInt(Sink downstream) { + public ChainedInt(Sink<? super E_OUT> downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -307,11 +305,10 @@ * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedLong implements Sink.OfLong { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedLong<E_OUT> implements Sink.OfLong { + protected final Sink<? super E_OUT> downstream; - public ChainedLong(Sink downstream) { + public ChainedLong(Sink<? super E_OUT> downstream) { this.downstream = Objects.requireNonNull(downstream); } @@ -340,11 +337,10 @@ * The implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ - static abstract class ChainedDouble implements Sink.OfDouble { - @SuppressWarnings("rawtypes") - protected final Sink downstream; + static abstract class ChainedDouble<E_OUT> implements Sink.OfDouble { + protected final Sink<? super E_OUT> downstream; - public ChainedDouble(Sink downstream) { + public ChainedDouble(Sink<? super E_OUT> downstream) { this.downstream = Objects.requireNonNull(downstream); }
--- a/src/share/classes/java/util/stream/SliceOps.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/SliceOps.java Tue Aug 27 12:27:31 2013 -0400 @@ -96,6 +96,11 @@ } } + @SuppressWarnings("unchecked") + private static <T> IntFunction<T[]> castingArray() { + return size -> (T[]) new Object[size]; + } + /** * Appends a "slice" operation to the provided stream. The slice operation * may be may be skip-only, limit-only, or skip-and-limit. @@ -107,12 +112,12 @@ * is to be imposed */ public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream, - long skip, long limit) { + long skip, long limit) { if (skip < 0) throw new IllegalArgumentException("Skip must be non-negative: " + skip); - return new ReferencePipeline.StatefulOp<T,T>(upstream, StreamShape.REFERENCE, - flags(limit)) { + return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE, + flags(limit)) { Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s, long skip, long limit, long sizeIfKnown) { if (skip <= sizeIfKnown) { @@ -146,7 +151,7 @@ // cancellation will be more aggressive cancelling later tasks // if the target slice size has been reached from a given task, // cancellation should also clear local results if any - return new SliceTask<>(this, helper, spliterator, i -> (T[]) new Object[i], skip, limit). + return new SliceTask<>(this, helper, spliterator, castingArray(), skip, limit). invoke().spliterator(); } } @@ -182,7 +187,7 @@ @Override Sink<T> opWrapSink(int flags, Sink<T> sink) { - return new Sink.ChainedReference<T>(sink) { + return new Sink.ChainedReference<T, T>(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -291,7 +296,7 @@ @Override Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) { - return new Sink.ChainedInt(sink) { + return new Sink.ChainedInt<Integer>(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -400,7 +405,7 @@ @Override Sink<Long> opWrapSink(int flags, Sink<Long> sink) { - return new Sink.ChainedLong(sink) { + return new Sink.ChainedLong<Long>(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -509,7 +514,7 @@ @Override Sink<Double> opWrapSink(int flags, Sink<Double> sink) { - return new Sink.ChainedDouble(sink) { + return new Sink.ChainedDouble<Double>(sink) { long n = skip; long m = limit >= 0 ? limit : Long.MAX_VALUE; @@ -560,13 +565,13 @@ private volatile boolean completed; - SliceTask(AbstractPipeline<?, P_OUT, ?> op, + SliceTask(AbstractPipeline<P_OUT, P_OUT, ?> op, PipelineHelper<P_OUT> helper, Spliterator<P_IN> spliterator, IntFunction<P_OUT[]> generator, long offset, long size) { super(helper, spliterator); - this.op = (AbstractPipeline<P_OUT, P_OUT, ?>) op; + this.op = op; this.generator = generator; this.targetOffset = offset; this.targetSize = size;
--- a/src/share/classes/java/util/stream/SortedOps.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/java/util/stream/SortedOps.java Tue Aug 27 12:27:31 2013 -0400 @@ -129,7 +129,7 @@ } @Override - public Sink<T> opWrapSink(int flags, Sink sink) { + public Sink<T> opWrapSink(int flags, Sink<T> sink) { Objects.requireNonNull(sink); // If the input is already naturally sorted and this operation @@ -280,12 +280,12 @@ /** * {@link ForkJoinTask} for implementing sort on SIZED reference streams. */ - private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T> { + private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T, T> { private final Comparator<? super T> comparator; private T[] array; private int offset; - SizedRefSortingSink(Sink<T> sink, Comparator<? super T> comparator) { + SizedRefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) { super(sink); this.comparator = comparator; } @@ -320,11 +320,11 @@ /** * {@link Sink} for implementing sort on reference streams. */ - private static final class RefSortingSink<T> extends Sink.ChainedReference<T> { + private static final class RefSortingSink<T> extends Sink.ChainedReference<T, T> { private final Comparator<? super T> comparator; private ArrayList<T> list; - RefSortingSink(Sink<T> sink, Comparator<? super T> comparator) { + RefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) { super(sink); this.comparator = comparator; } @@ -352,11 +352,11 @@ /** * {@link Sink} for implementing sort on SIZED int streams. */ - private static final class SizedIntSortingSink extends Sink.ChainedInt { + private static final class SizedIntSortingSink extends Sink.ChainedInt<Integer> { private int[] array; private int offset; - SizedIntSortingSink(Sink downstream) { + SizedIntSortingSink(Sink<? super Integer> downstream) { super(downstream); } @@ -386,10 +386,10 @@ /** * {@link Sink} for implementing sort on int streams. */ - private static final class IntSortingSink extends Sink.ChainedInt { + private static final class IntSortingSink extends Sink.ChainedInt<Integer> { private SpinedBuffer.OfInt b; - IntSortingSink(Sink sink) { + IntSortingSink(Sink<? super Integer> sink) { super(sink); } @@ -417,11 +417,11 @@ /** * {@link Sink} for implementing sort on SIZED long streams. */ - private static final class SizedLongSortingSink extends Sink.ChainedLong { + private static final class SizedLongSortingSink extends Sink.ChainedLong<Long> { private long[] array; private int offset; - SizedLongSortingSink(Sink downstream) { + SizedLongSortingSink(Sink<? super Long> downstream) { super(downstream); } @@ -451,10 +451,10 @@ /** * {@link Sink} for implementing sort on long streams. */ - private static final class LongSortingSink extends Sink.ChainedLong { + private static final class LongSortingSink extends Sink.ChainedLong<Long> { private SpinedBuffer.OfLong b; - LongSortingSink(Sink sink) { + LongSortingSink(Sink<? super Long> sink) { super(sink); } @@ -482,11 +482,11 @@ /** * {@link Sink} for implementing sort on SIZED double streams. */ - private static final class SizedDoubleSortingSink extends Sink.ChainedDouble { + private static final class SizedDoubleSortingSink extends Sink.ChainedDouble<Double> { private double[] array; private int offset; - SizedDoubleSortingSink(Sink downstream) { + SizedDoubleSortingSink(Sink<? super Double> downstream) { super(downstream); } @@ -516,10 +516,10 @@ /** * {@link Sink} for implementing sort on double streams. */ - private static final class DoubleSortingSink extends Sink.ChainedDouble { + private static final class DoubleSortingSink extends Sink.ChainedDouble<Double> { private SpinedBuffer.OfDouble b; - DoubleSortingSink(Sink sink) { + DoubleSortingSink(Sink<? super Double> sink) { super(sink); }
--- a/src/share/classes/javax/security/auth/Policy.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/javax/security/auth/Policy.java Tue Aug 27 12:27:31 2013 -0400 @@ -156,9 +156,10 @@ private static Policy policy; private static ClassLoader contextClassLoader; + private final static String AUTH_POLICY = + "sun.security.provider.AuthPolicyFile"; - // true if a custom (not com.sun.security.auth.PolicyFile) system-wide - // policy object is set + // true if a custom (not AUTH_POLICY) system-wide policy object is set private static boolean isCustomPolicy; static { @@ -220,7 +221,7 @@ } }); if (policy_class == null) { - policy_class = "com.sun.security.auth.PolicyFile"; + policy_class = AUTH_POLICY; } try { @@ -236,8 +237,7 @@ contextClassLoader).newInstance(); } }); - isCustomPolicy = - !finalClass.equals("com.sun.security.auth.PolicyFile"); + isCustomPolicy = !finalClass.equals(AUTH_POLICY); } catch (Exception e) { throw new SecurityException (sun.security.util.ResourcesMgr.getString @@ -274,14 +274,14 @@ } /** - * Returns true if a custom (not com.sun.security.auth.PolicyFile) - * system-wide policy object has been set or installed. This method is - * called by SubjectDomainCombiner to provide backwards compatibility for + * Returns true if a custom (not AUTH_POLICY) system-wide policy object + * has been set or installed. This method is called by + * SubjectDomainCombiner to provide backwards compatibility for * developers that provide their own javax.security.auth.Policy * implementations. * - * @return true if a custom (not com.sun.security.auth.PolicyFile) - * system-wide policy object has been set; false otherwise + * @return true if a custom (not AUTH_POLICY) system-wide policy object + * has been set; false otherwise */ static boolean isCustomPolicySet(Debug debug) { if (policy != null) { @@ -299,8 +299,7 @@ return Security.getProperty("auth.policy.provider"); } }); - if (policyClass != null - && !policyClass.equals("com.sun.security.auth.PolicyFile")) { + if (policyClass != null && !policyClass.equals(AUTH_POLICY)) { if (debug != null) { debug.println("Providing backwards compatibility for " + "javax.security.auth.policy implementation: " +
--- a/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Tue Aug 27 12:27:31 2013 -0400 @@ -197,8 +197,7 @@ * {@code KerberosPrincipal} and the two * {@code KerberosPrincipal} instances are equivalent. * More formally two {@code KerberosPrincipal} instances are equal - * if the values returned by {@code getName()} are equal and the - * values returned by {@code getNameType()} are equal. + * if the values returned by {@code getName()} are equal. * * @param other the Object to compare to * @return true if the Object passed in represents the same principal @@ -211,15 +210,10 @@ if (! (other instanceof KerberosPrincipal)) { return false; - } else { - String myFullName = getName(); - String otherFullName = ((KerberosPrincipal) other).getName(); - if (nameType == ((KerberosPrincipal)other).nameType && - myFullName.equals(otherFullName)) { - return true; - } } - return false; + String myFullName = getName(); + String otherFullName = ((KerberosPrincipal) other).getName(); + return myFullName.equals(otherFullName); } /**
--- a/src/share/classes/javax/sound/sampled/DataLine.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/javax/sound/sampled/DataLine.java Tue Aug 27 12:27:31 2013 -0400 @@ -25,6 +25,8 @@ package javax.sound.sampled; +import java.util.Arrays; + /** * <code>DataLine</code> adds media-related functionality to its * superinterface, <code>{@link Line}</code>. This functionality includes @@ -282,9 +284,9 @@ */ public static class Info extends Line.Info { - private AudioFormat[] formats; - private int minBufferSize; - private int maxBufferSize; + private final AudioFormat[] formats; + private final int minBufferSize; + private final int maxBufferSize; /** * Constructs a data line's info object from the specified information, @@ -304,7 +306,7 @@ if (formats == null) { this.formats = new AudioFormat[0]; } else { - this.formats = formats; + this.formats = Arrays.copyOf(formats, formats.length); } this.minBufferSize = minBufferSize; @@ -329,8 +331,7 @@ if (format == null) { this.formats = new AudioFormat[0]; } else { - AudioFormat[] formats = { format }; - this.formats = formats; + this.formats = new AudioFormat[]{format}; } this.minBufferSize = bufferSize; @@ -373,10 +374,7 @@ * @see #isFormatSupported(AudioFormat) */ public AudioFormat[] getFormats() { - - AudioFormat[] returnedArray = new AudioFormat[formats.length]; - System.arraycopy(formats, 0, returnedArray, 0, formats.length); - return returnedArray; + return Arrays.copyOf(formats, formats.length); } /**
--- a/src/share/classes/javax/swing/JLabel.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/javax/swing/JLabel.java Tue Aug 27 12:27:31 2013 -0400 @@ -1185,14 +1185,13 @@ } /** - * Determine the bounding box of the character at the given - * index into the string. The bounds are returned in local - * coordinates. If the index is invalid an empty rectangle is - * returned. + * Returns the bounding box of the character at the given + * index in the string. The bounds are returned in local + * coordinates. If the index is invalid, <code>null</code> is returned. * * @param i the index into the String - * @return the screen coordinates of the character's the bounding box, - * if index is invalid returns an empty rectangle. + * @return the screen coordinates of the character's bounding box. + * If the index is invalid, <code>null</code> is returned. * @since 1.3 */ public Rectangle getCharacterBounds(int i) {
--- a/src/share/classes/sun/audio/AudioData.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/audio/AudioData.java Tue Aug 27 12:27:31 2013 -0400 @@ -26,6 +26,8 @@ package sun.audio; import java.io.*; +import java.util.Arrays; + import javax.sound.sampled.*; @@ -65,12 +67,11 @@ /** * Constructor */ - public AudioData(byte buffer[]) { - - this.buffer = buffer; - // if we cannot extract valid format information, we resort to assuming the data will be 8k mono u-law - // in order to provide maximal backwards compatibility.... - this.format = DEFAULT_FORMAT; + public AudioData(final byte[] buffer) { + // if we cannot extract valid format information, we resort to assuming + // the data will be 8k mono u-law in order to provide maximal backwards + // compatibility.... + this(DEFAULT_FORMAT, buffer); // okay, we need to extract the format and the byte buffer of data try { @@ -90,9 +91,10 @@ * Non-public constructor; this is the one we use in ADS and CADS * constructors. */ - AudioData(AudioFormat format, byte[] buffer) { - + AudioData(final AudioFormat format, final byte[] buffer) { this.format = format; - this.buffer = buffer; + if (buffer != null) { + this.buffer = Arrays.copyOf(buffer, buffer.length); + } } }
--- a/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/awt/datatransfer/ClipboardTransferable.java Tue Aug 27 12:27:31 2013 -0400 @@ -98,8 +98,7 @@ } flavors = DataTransferer.getInstance(). - setToSortedDataFlavorArray(flavorsToData.keySet(), - flavorsForFormats); + setToSortedDataFlavorArray(flavorsToData.keySet()); } } finally { clipboard.closeClipboard();
--- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java Tue Aug 27 12:27:31 2013 -0400 @@ -2406,15 +2406,6 @@ } /** - * Helper function to reduce a Map with DataFlavor keys to a DataFlavor - * array. The array will be sorted according to - * <code>DataFlavorComparator</code>. - */ - public static DataFlavor[] keysToDataFlavorArray(Map map) { - return setToSortedDataFlavorArray(map.keySet(), map); - } - - /** * Helper function to convert a Set of DataFlavors to a sorted array. * The array will be sorted according to <code>DataFlavorComparator</code>. */ @@ -2428,24 +2419,6 @@ } /** - * Helper function to convert a Set of DataFlavors to a sorted array. - * The array will be sorted according to a - * <code>DataFlavorComparator</code> created with the specified - * flavor-to-native map as an argument. - */ - public static DataFlavor[] setToSortedDataFlavorArray - (Set flavorsSet, Map flavorToNativeMap) - { - DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; - flavorsSet.toArray(flavors); - Comparator comparator = - new DataFlavorComparator(flavorToNativeMap, - IndexedComparator.SELECT_WORST); - Arrays.sort(flavors, comparator); - return flavors; - } - - /** * Helper function to convert an InputStream to a byte[] array. */ protected static byte[] inputStreamToByteArray(InputStream str) @@ -2724,11 +2697,9 @@ * application/x-java-* MIME types. Unknown application types are preferred * because if the user provides his own data flavor, it will likely be the * most descriptive one. For flavors which are otherwise equal, the - * flavors' native formats are compared, with greater long values - * taking precedence. + * flavors' string representation are compared in the alphabetical order. */ public static class DataFlavorComparator extends IndexedComparator { - protected final Map flavorToFormatMap; private final CharsetComparator charsetComparator; @@ -2864,20 +2835,6 @@ super(order); charsetComparator = new CharsetComparator(order); - flavorToFormatMap = Collections.EMPTY_MAP; - } - - public DataFlavorComparator(Map map) { - this(map, SELECT_BEST); - } - - public DataFlavorComparator(Map map, boolean order) { - super(order); - - charsetComparator = new CharsetComparator(order); - HashMap hashMap = new HashMap(map.size()); - hashMap.putAll(map); - flavorToFormatMap = Collections.unmodifiableMap(hashMap); } public int compare(Object obj1, Object obj2) { @@ -2973,10 +2930,9 @@ } } - // As a last resort, take the DataFlavor with the greater integer - // format. - return compareLongs(flavorToFormatMap, flavor1, flavor2, - UNKNOWN_OBJECT_LOSES_L); + // The flavours are not equal but still not distinguishable. + // Compare String representations in alphabetical order + return flavor1.getMimeType().compareTo(flavor2.getMimeType()); } }
--- a/src/share/classes/sun/misc/Compare.java Tue Aug 27 12:04:32 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 1996, 1997, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/** - * Compare: an interface to enable users to define the result of - * a comparison of two objects. - * - * @author Sunita Mani - */ - -package sun.misc; - -public interface Compare { - - /** - * doCompare - * - * @param obj1 first object to compare. - * @param obj2 second object to compare. - * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2. - */ - public int doCompare(Object obj1, Object obj2); - -}
--- a/src/share/classes/sun/misc/Sort.java Tue Aug 27 12:04:32 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved. - * 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. - */ - -/** - * Sort: a class that uses the quicksort algorithm to sort an - * array of objects. - * - * @author Sunita Mani - */ - -package sun.misc; - -public class Sort { - - private static void swap(Object arr[], int i, int j) { - Object tmp; - - tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } - - /** - * quicksort the array of objects. - * - * @param arr[] - an array of objects - * @param left - the start index - from where to begin sorting - * @param right - the last index. - * @param comp - an object that implemnts the Compare interface to resolve thecomparison. - */ - public static void quicksort(Object arr[], int left, int right, Compare comp) { - int i, last; - - if (left >= right) { /* do nothing if array contains fewer than two */ - return; /* two elements */ - } - swap(arr, left, (left+right) / 2); - last = left; - for (i = left+1; i <= right; i++) { - if (comp.doCompare(arr[i], arr[left]) < 0) { - swap(arr, ++last, i); - } - } - swap(arr, left, last); - quicksort(arr, left, last-1, comp); - quicksort(arr, last+1, right, comp); - } - - public static void quicksort(Object arr[], Compare comp) { - quicksort(arr, 0, arr.length-1, comp); - } -}
--- a/src/share/classes/sun/print/PSPrinterJob.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/print/PSPrinterJob.java Tue Aug 27 12:27:31 2013 -0400 @@ -339,6 +339,8 @@ */ private static Properties mFontProps = null; + private static boolean isMac; + /* Class static initialiser block */ static { //enable priviledges so initProps can access system properties, @@ -347,6 +349,8 @@ new java.security.PrivilegedAction() { public Object run() { mFontProps = initProps(); + String osName = System.getProperty("os.name"); + isMac = osName.startsWith("Mac"); return null; } }); @@ -473,6 +477,12 @@ PrintService pServ = getPrintService(); if (pServ != null) { mDestination = pServ.getName(); + if (isMac) { + PrintServiceAttributeSet psaSet = pServ.getAttributes() ; + if (psaSet != null) { + mDestination = psaSet.get(PrinterName.class).toString(); + } + } } } } @@ -771,6 +781,12 @@ PrintService pServ = getPrintService(); if (pServ != null) { mDestination = pServ.getName(); + if (isMac) { + PrintServiceAttributeSet psaSet = pServ.getAttributes(); + if (psaSet != null) { + mDestination = psaSet.get(PrinterName.class).toString() ; + } + } } PrinterSpooler spooler = new PrinterSpooler(); java.security.AccessController.doPrivileged(spooler);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/provider/AuthPolicyFile.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,1195 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import java.io.*; +import java.lang.reflect.*; +import java.net.URL; +import java.util.*; + +import java.security.AccessController; +import java.security.CodeSource; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Permission; +import java.security.Permissions; +import java.security.PermissionCollection; +import java.security.Principal; +import java.security.PrivilegedAction; +import java.security.UnresolvedPermission; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; + +import javax.security.auth.Subject; +import javax.security.auth.PrivateCredentialPermission; + +import sun.security.provider.PolicyParser.GrantEntry; +import sun.security.provider.PolicyParser.PermissionEntry; +import sun.security.provider.PolicyParser.PrincipalEntry; +import sun.security.util.Debug; +import sun.security.util.PolicyUtil; +import sun.security.util.PropertyExpander; + +/** + * See {@code com.sun.security.auth.PolicyFile} for the class description. + * This class is necessary in order to support a default + * {@code javax.security.auth.Policy} implementation on the compact1 and + * compact2 profiles. + * + * @deprecated As of JDK 1.4, replaced by + * {@code sun.security.provider.PolicyFile}. + * This class is entirely deprecated. + */ +@Deprecated +public class AuthPolicyFile extends javax.security.auth.Policy { + + static final ResourceBundle rb = + AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() { + @Override public ResourceBundle run() { + return (ResourceBundle.getBundle + ("sun.security.util.AuthResources")); + } + }); + + private static final Debug debug = Debug.getInstance("policy", + "\t[Auth Policy]"); + + private static final String AUTH_POLICY = "java.security.auth.policy"; + private static final String SECURITY_MANAGER = "java.security.manager"; + private static final String AUTH_POLICY_URL = "auth.policy.url."; + + private Vector<PolicyEntry> policyEntries; + private Hashtable<Object, Object> aliasMapping; + + private boolean initialized = false; + + private boolean expandProperties = true; + private boolean ignoreIdentityScope = true; + + // for use with the reflection API + private static final Class[] PARAMS = { String.class, String.class}; + + /** + * Initializes the Policy object and reads the default policy + * configuration file(s) into the Policy object. + */ + public AuthPolicyFile() { + // initialize Policy if either the AUTH_POLICY or + // SECURITY_MANAGER properties are set + String prop = System.getProperty(AUTH_POLICY); + + if (prop == null) { + prop = System.getProperty(SECURITY_MANAGER); + } + if (prop != null) { + init(); + } + } + + private synchronized void init() { + if (initialized) { + return; + } + + policyEntries = new Vector<PolicyEntry>(); + aliasMapping = new Hashtable<Object, Object>(11); + + initPolicyFile(); + initialized = true; + } + + @Override + public synchronized void refresh() { + + java.lang.SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new javax.security.auth.AuthPermission + ("refreshPolicy")); + } + + // XXX + // + // 1) if code instantiates PolicyFile directly, then it will need + // all the permissions required for the PolicyFile initialization + // 2) if code calls Policy.getPolicy, then it simply needs + // AuthPermission(getPolicy), and the javax.security.auth.Policy + // implementation instantiates PolicyFile in a doPrivileged block + // 3) if after instantiating a Policy (either via #1 or #2), + // code calls refresh, it simply needs + // AuthPermission(refreshPolicy). then PolicyFile wraps + // the refresh in a doPrivileged block. + initialized = false; + AccessController.doPrivileged(new PrivilegedAction<Void>() { + @Override public Void run() { + init(); + return null; + } + }); + } + + private KeyStore initKeyStore(URL policyUrl, String keyStoreName, + String keyStoreType) { + if (keyStoreName != null) { + try { + /* + * location of keystore is specified as absolute URL in policy + * file, or is relative to URL of policy file + */ + URL keyStoreUrl = null; + try { + keyStoreUrl = new URL(keyStoreName); + // absolute URL + } catch (java.net.MalformedURLException e) { + // relative URL + keyStoreUrl = new URL(policyUrl, keyStoreName); + } + + if (debug != null) { + debug.println("reading keystore"+keyStoreUrl); + } + + InputStream inStream = new BufferedInputStream( + PolicyUtil.getInputStream(keyStoreUrl)); + + KeyStore ks; + if (keyStoreType != null) + ks = KeyStore.getInstance(keyStoreType); + else + ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(inStream, null); + inStream.close(); + return ks; + } catch (Exception e) { + // ignore, treat it like we have no keystore + if (debug != null) { + e.printStackTrace(); + } + return null; + } + } + return null; + } + + private void initPolicyFile() { + + String prop = Security.getProperty("policy.expandProperties"); + if (prop != null) { + expandProperties = prop.equalsIgnoreCase("true"); + } + + String iscp = Security.getProperty("policy.ignoreIdentityScope"); + if (iscp != null) { + ignoreIdentityScope = iscp.equalsIgnoreCase("true"); + } + + String allowSys = Security.getProperty("policy.allowSystemProperty"); + if (allowSys != null && allowSys.equalsIgnoreCase("true")) { + String extra_policy = System.getProperty(AUTH_POLICY); + if (extra_policy != null) { + boolean overrideAll = false; + if (extra_policy.startsWith("=")) { + overrideAll = true; + extra_policy = extra_policy.substring(1); + } + try { + extra_policy = PropertyExpander.expand(extra_policy); + URL policyURL; + File policyFile = new File(extra_policy); + if (policyFile.exists()) { + policyURL = + new URL("file:" + policyFile.getCanonicalPath()); + } else { + policyURL = new URL(extra_policy); + } + if (debug != null) { + debug.println("reading " + policyURL); + } + init(policyURL); + } catch (Exception e) { + // ignore. + if (debug != null) { + debug.println("caught exception: " + e); + } + + } + if (overrideAll) { + if (debug != null) { + debug.println("overriding other policies!"); + } + return; + } + } + } + + int n = 1; + boolean loaded_one = false; + String policy_url; + + while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) { + try { + policy_url = PropertyExpander.expand(policy_url).replace + (File.separatorChar, '/'); + if (debug != null) { + debug.println("reading " + policy_url); + } + init(new URL(policy_url)); + loaded_one = true; + } catch (Exception e) { + if (debug != null) { + debug.println("error reading policy " + e); + e.printStackTrace(); + } + // ignore that policy + } + n++; + } + + if (loaded_one == false) { + // do not load a static policy + } + } + + /** + * Checks public key. If it is marked as trusted in + * the identity database, add it to the policy + * with the AllPermission. + */ + private boolean checkForTrustedIdentity(final Certificate cert) { + return false; + } + + /** + * Reads a policy configuration into the Policy object using a + * Reader object. + * + * @param policyFile the policy Reader object. + */ + private void init(URL policy) { + PolicyParser pp = new PolicyParser(expandProperties); + try (InputStreamReader isr + = new InputStreamReader(PolicyUtil.getInputStream(policy))) { + pp.read(isr); + KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(), + pp.getKeyStoreType()); + Enumeration<GrantEntry> enum_ = pp.grantElements(); + while (enum_.hasMoreElements()) { + GrantEntry ge = enum_.nextElement(); + addGrantEntry(ge, keyStore); + } + } catch (PolicyParser.ParsingException pe) { + System.err.println(AUTH_POLICY + + rb.getString(".error.parsing.") + policy); + System.err.println(AUTH_POLICY + rb.getString("COLON") + + pe.getMessage()); + if (debug != null) { + pe.printStackTrace(); + } + } catch (Exception e) { + if (debug != null) { + debug.println("error parsing " + policy); + debug.println(e.toString()); + e.printStackTrace(); + } + } + } + + /** + * Given a PermissionEntry, create a codeSource. + * + * @return null if signedBy alias is not recognized + */ + CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore) + throws java.net.MalformedURLException + { + Certificate[] certs = null; + if (ge.signedBy != null) { + certs = getCertificates(keyStore, ge.signedBy); + if (certs == null) { + // we don't have a key for this alias, + // just return + if (debug != null) { + debug.println(" no certs for alias " + + ge.signedBy + ", ignoring."); + } + return null; + } + } + + URL location; + if (ge.codeBase != null) { + location = new URL(ge.codeBase); + } else { + location = null; + } + + if (ge.principals == null || ge.principals.size() == 0) { + return (canonicalizeCodebase + (new CodeSource(location, certs), + false)); + } else { + return (canonicalizeCodebase + (new SubjectCodeSource(null, ge.principals, location, certs), + false)); + } + } + + /** + * Add one policy entry to the vector. + */ + private void addGrantEntry(GrantEntry ge, KeyStore keyStore) { + + if (debug != null) { + debug.println("Adding policy entry: "); + debug.println(" signedBy " + ge.signedBy); + debug.println(" codeBase " + ge.codeBase); + if (ge.principals != null) { + for (PrincipalEntry pppe : ge.principals) { + debug.println(" " + pppe.getPrincipalClass() + + " " + pppe.getPrincipalName()); + } + } + debug.println(); + } + + try { + CodeSource codesource = getCodeSource(ge, keyStore); + // skip if signedBy alias was unknown... + if (codesource == null) return; + + PolicyEntry entry = new PolicyEntry(codesource); + Enumeration<PermissionEntry> enum_ = ge.permissionElements(); + while (enum_.hasMoreElements()) { + PermissionEntry pe = enum_.nextElement(); + try { + // XXX special case PrivateCredentialPermission-SELF + Permission perm; + if (pe.permission.equals + ("javax.security.auth.PrivateCredentialPermission") && + pe.name.endsWith(" self")) { + perm = getInstance(pe.permission, + pe.name + " \"self\"", + pe.action); + } else { + perm = getInstance(pe.permission, + pe.name, + pe.action); + } + entry.add(perm); + if (debug != null) { + debug.println(" "+perm); + } + } catch (ClassNotFoundException cnfe) { + Certificate certs[]; + if (pe.signedBy != null) { + certs = getCertificates(keyStore, pe.signedBy); + } else { + certs = null; + } + + // only add if we had no signer or we had a + // a signer and found the keys for it. + if (certs != null || pe.signedBy == null) { + Permission perm = new UnresolvedPermission( + pe.permission, + pe.name, + pe.action, + certs); + entry.add(perm); + if (debug != null) { + debug.println(" "+perm); + } + } + } catch (java.lang.reflect.InvocationTargetException ite) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Permission.") + + pe.permission + + rb.getString("SPACE") + + ite.getTargetException()); + } catch (Exception e) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Permission.") + + pe.permission + + rb.getString("SPACE") + + e); + } + } + policyEntries.addElement(entry); + } catch (Exception e) { + System.err.println + (AUTH_POLICY + + rb.getString(".error.adding.Entry.") + + ge + + rb.getString("SPACE") + + e); + } + + if (debug != null) { + debug.println(); + } + } + + /** + * Returns a new Permission object of the given Type. The Permission is + * created by getting the + * Class object using the <code>Class.forName</code> method, and using + * the reflection API to invoke the (String name, String actions) + * constructor on the + * object. + * + * @param type the type of Permission being created. + * @param name the name of the Permission being created. + * @param actions the actions of the Permission being created. + * + * @exception ClassNotFoundException if the particular Permission + * class could not be found. + * + * @exception IllegalAccessException if the class or initializer is + * not accessible. + * + * @exception InstantiationException if getInstance tries to + * instantiate an abstract class or an interface, or if the + * instantiation fails for some other reason. + * + * @exception NoSuchMethodException if the (String, String) constructor + * is not found. + * + * @exception InvocationTargetException if the underlying Permission + * constructor throws an exception. + * + */ + private static final Permission getInstance(String type, + String name, + String actions) + throws ClassNotFoundException, + InstantiationException, + IllegalAccessException, + NoSuchMethodException, + InvocationTargetException + { + //XXX we might want to keep a hash of created factories... + Class<?> pc = Class.forName(type); + Constructor<?> c = pc.getConstructor(PARAMS); + return (Permission) c.newInstance(new Object[] { name, actions }); + } + + /** + * Fetch all certs associated with this alias. + */ + Certificate[] getCertificates(KeyStore keyStore, String aliases) { + + Vector<Certificate> vcerts = null; + + StringTokenizer st = new StringTokenizer(aliases, ","); + int n = 0; + + while (st.hasMoreTokens()) { + String alias = st.nextToken().trim(); + n++; + Certificate cert = null; + // See if this alias's cert has already been cached + cert = (Certificate) aliasMapping.get(alias); + if (cert == null && keyStore != null) { + + try { + cert = keyStore.getCertificate(alias); + } catch (KeyStoreException kse) { + // never happens, because keystore has already been loaded + // when we call this + } + if (cert != null) { + aliasMapping.put(alias, cert); + aliasMapping.put(cert, alias); + } + } + + if (cert != null) { + if (vcerts == null) { + vcerts = new Vector<Certificate>(); + } + vcerts.addElement(cert); + } + } + + // make sure n == vcerts.size, since we are doing a logical *and* + if (vcerts != null && n == vcerts.size()) { + Certificate[] certs = new Certificate[vcerts.size()]; + vcerts.copyInto(certs); + return certs; + } else { + return null; + } + } + + /** + * Enumerate all the entries in the global policy object. + * This method is used by policy admin tools. The tools + * should use the Enumeration methods on the returned object + * to fetch the elements sequentially. + */ + private final synchronized Enumeration<PolicyEntry> elements() { + return policyEntries.elements(); + } + + @Override + public PermissionCollection getPermissions(final Subject subject, + final CodeSource codesource) { + + // 1) if code instantiates PolicyFile directly, then it will need + // all the permissions required for the PolicyFile initialization + // 2) if code calls Policy.getPolicy, then it simply needs + // AuthPermission(getPolicy), and the javax.security.auth.Policy + // implementation instantiates PolicyFile in a doPrivileged block + // 3) if after instantiating a Policy (either via #1 or #2), + // code calls getPermissions, PolicyFile wraps the call + // in a doPrivileged block. + return AccessController.doPrivileged + (new PrivilegedAction<PermissionCollection>() { + @Override public PermissionCollection run() { + SubjectCodeSource scs = new SubjectCodeSource( + subject, null, + codesource == null ? null : codesource.getLocation(), + codesource == null ? null : codesource.getCertificates()); + if (initialized) { + return getPermissions(new Permissions(), scs); + } else { + return new PolicyPermissions(AuthPolicyFile.this, scs); + } + } + }); + } + + /** + * Examines the global policy for the specified CodeSource, and + * creates a PermissionCollection object with + * the set of permissions for that principal's protection domain. + * + * @param CodeSource the codesource associated with the caller. + * This encapsulates the original location of the code (where the code + * came from) and the public key(s) of its signer. + * + * @return the set of permissions according to the policy. + */ + PermissionCollection getPermissions(CodeSource codesource) { + + if (initialized) { + return getPermissions(new Permissions(), codesource); + } else { + return new PolicyPermissions(this, codesource); + } + } + + /** + * Examines the global policy for the specified CodeSource, and + * creates a PermissionCollection object with + * the set of permissions for that principal's protection domain. + * + * @param permissions the permissions to populate + * @param codesource the codesource associated with the caller. + * This encapsulates the original location of the code (where the code + * came from) and the public key(s) of its signer. + * + * @return the set of permissions according to the policy. + */ + Permissions getPermissions(final Permissions perms, + final CodeSource cs) + { + if (!initialized) { + init(); + } + + final CodeSource codesource[] = {null}; + + codesource[0] = canonicalizeCodebase(cs, true); + + if (debug != null) { + debug.println("evaluate(" + codesource[0] + ")\n"); + } + + // needs to be in a begin/endPrivileged block because + // codesource.implies calls URL.equals which does an + // InetAddress lookup + + for (int i = 0; i < policyEntries.size(); i++) { + + PolicyEntry entry = policyEntries.elementAt(i); + + if (debug != null) { + debug.println("PolicyFile CodeSource implies: " + + entry.codesource.toString() + "\n\n" + + "\t" + codesource[0].toString() + "\n\n"); + } + + if (entry.codesource.implies(codesource[0])) { + for (int j = 0; j < entry.permissions.size(); j++) { + Permission p = entry.permissions.elementAt(j); + if (debug != null) { + debug.println(" granting " + p); + } + if (!addSelfPermissions(p, entry.codesource, + codesource[0], perms)) { + // we could check for duplicates + // before adding new permissions, + // but the SubjectDomainCombiner + // already checks for duplicates later + perms.add(p); + } + } + } + } + + // now see if any of the keys are trusted ids. + + if (!ignoreIdentityScope) { + Certificate certs[] = codesource[0].getCertificates(); + if (certs != null) { + for (int k=0; k < certs.length; k++) { + if (aliasMapping.get(certs[k]) == null && + checkForTrustedIdentity(certs[k])) { + // checkForTrustedIdentity added it + // to the policy for us. next time + // around we'll find it. This time + // around we need to add it. + perms.add(new java.security.AllPermission()); + } + } + } + } + return perms; + } + + /** + * Returns true if 'Self' permissions were added to the provided + * 'perms', and false otherwise. + * + * <p> + * + * @param p check to see if this Permission is a "SELF" + * PrivateCredentialPermission. <p> + * + * @param entryCs the codesource for the Policy entry. + * + * @param accCs the codesource for from the current AccessControlContext. + * + * @param perms the PermissionCollection where the individual + * PrivateCredentialPermissions will be added. + */ + private boolean addSelfPermissions(final Permission p, + CodeSource entryCs, + CodeSource accCs, + Permissions perms) { + + if (!(p instanceof PrivateCredentialPermission)) { + return false; + } + + if (!(entryCs instanceof SubjectCodeSource)) { + return false; + } + + PrivateCredentialPermission pcp = (PrivateCredentialPermission)p; + SubjectCodeSource scs = (SubjectCodeSource)entryCs; + + // see if it is a SELF permission + String[][] pPrincipals = pcp.getPrincipals(); + if (pPrincipals.length <= 0 || + !pPrincipals[0][0].equalsIgnoreCase("self") || + !pPrincipals[0][1].equalsIgnoreCase("self")) { + + // regular PrivateCredentialPermission + return false; + } else { + + // granted a SELF permission - create a + // PrivateCredentialPermission for each + // of the Policy entry's CodeSource Principals + + if (scs.getPrincipals() == null) { + // XXX SubjectCodeSource has no Subject??? + return true; + } + + for (PrincipalEntry principal : scs.getPrincipals()) { + + // if the Policy entry's Principal does not contain a + // WILDCARD for the Principal name, then a + // new PrivateCredentialPermission is created + // for the Principal listed in the Policy entry. + // if the Policy entry's Principal contains a WILDCARD + // for the Principal name, then a new + // PrivateCredentialPermission is created + // for each Principal associated with the Subject + // in the current ACC. + + String[][] principalInfo = getPrincipalInfo(principal, accCs); + + for (int i = 0; i < principalInfo.length; i++) { + + // here's the new PrivateCredentialPermission + + PrivateCredentialPermission newPcp = + new PrivateCredentialPermission + (pcp.getCredentialClass() + + " " + + principalInfo[i][0] + + " " + + "\"" + principalInfo[i][1] + "\"", + "read"); + + if (debug != null) { + debug.println("adding SELF permission: " + + newPcp.toString()); + } + + perms.add(newPcp); + } + } + } + return true; + } + + /** + * return the principal class/name pair in the 2D array. + * array[x][y]: x corresponds to the array length. + * if (y == 0), it's the principal class. + * if (y == 1), it's the principal name. + */ + private String[][] getPrincipalInfo(PrincipalEntry principal, + final CodeSource accCs) { + + // there are 3 possibilities: + // 1) the entry's Principal class and name are not wildcarded + // 2) the entry's Principal name is wildcarded only + // 3) the entry's Principal class and name are wildcarded + + if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + !principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { + + // build a PrivateCredentialPermission for the principal + // from the Policy entry + String[][] info = new String[1][2]; + info[0][0] = principal.getPrincipalClass(); + info[0][1] = principal.getPrincipalName(); + return info; + + } else if (!principal.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) && + principal.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME)) { + + // build a PrivateCredentialPermission for all + // the Subject's principals that are instances of principalClass + + // the accCs is guaranteed to be a SubjectCodeSource + // because the earlier CodeSource.implies succeeded + SubjectCodeSource scs = (SubjectCodeSource)accCs; + + Set<? extends Principal> principalSet = null; + try { + // principal.principalClass should extend Principal + // If it doesn't, we should stop here with a ClassCastException. + @SuppressWarnings("unchecked") + Class<? extends Principal> pClass = (Class<? extends Principal>) + Class.forName(principal.getPrincipalClass(), false, + ClassLoader.getSystemClassLoader()); + principalSet = scs.getSubject().getPrincipals(pClass); + } catch (Exception e) { + if (debug != null) { + debug.println("problem finding Principal Class " + + "when expanding SELF permission: " + + e.toString()); + } + } + + if (principalSet == null) { + // error + return new String[0][0]; + } + + String[][] info = new String[principalSet.size()][2]; + + int i = 0; + for (Principal p : principalSet) { + info[i][0] = p.getClass().getName(); + info[i][1] = p.getName(); + i++; + } + return info; + + } else { + + // build a PrivateCredentialPermission for every + // one of the current Subject's principals + + // the accCs is guaranteed to be a SubjectCodeSource + // because the earlier CodeSource.implies succeeded + SubjectCodeSource scs = (SubjectCodeSource)accCs; + Set<Principal> principalSet = scs.getSubject().getPrincipals(); + + String[][] info = new String[principalSet.size()][2]; + + int i = 0; + for (Principal p : principalSet) { + info[i][0] = p.getClass().getName(); + info[i][1] = p.getName(); + i++; + } + return info; + } + } + + /* + * Returns the signer certificates from the list of certificates associated + * with the given code source. + * + * The signer certificates are those certificates that were used to verify + * signed code originating from the codesource location. + * + * This method assumes that in the given code source, each signer + * certificate is followed by its supporting certificate chain + * (which may be empty), and that the signer certificate and its + * supporting certificate chain are ordered bottom-to-top (i.e., with the + * signer certificate first and the (root) certificate authority last). + */ + Certificate[] getSignerCertificates(CodeSource cs) { + Certificate[] certs = null; + if ((certs = cs.getCertificates()) == null) { + return null; + } + for (int i = 0; i < certs.length; i++) { + if (!(certs[i] instanceof X509Certificate)) + return cs.getCertificates(); + } + + // Do we have to do anything? + int i = 0; + int count = 0; + while (i < certs.length) { + count++; + while (((i+1) < certs.length) + && ((X509Certificate)certs[i]).getIssuerDN().equals( + ((X509Certificate)certs[i+1]).getSubjectDN())) { + i++; + } + i++; + } + if (count == certs.length) { + // Done + return certs; + } + + ArrayList<Certificate> userCertList = new ArrayList<>(); + i = 0; + while (i < certs.length) { + userCertList.add(certs[i]); + while (((i+1) < certs.length) + && ((X509Certificate)certs[i]).getIssuerDN().equals( + ((X509Certificate)certs[i+1]).getSubjectDN())) { + i++; + } + i++; + } + Certificate[] userCerts = new Certificate[userCertList.size()]; + userCertList.toArray(userCerts); + return userCerts; + } + + private CodeSource canonicalizeCodebase(CodeSource cs, + boolean extractSignerCerts) { + CodeSource canonCs = cs; + if (cs.getLocation() != null && + cs.getLocation().getProtocol().equalsIgnoreCase("file")) { + try { + String path = cs.getLocation().getFile().replace + ('/', + File.separatorChar); + URL csUrl = null; + if (path.endsWith("*")) { + // remove trailing '*' because it causes canonicalization + // to fail on win32 + path = path.substring(0, path.length()-1); + boolean appendFileSep = false; + if (path.endsWith(File.separator)) { + appendFileSep = true; + } + if (path.equals("")) { + path = System.getProperty("user.dir"); + } + File f = new File(path); + path = f.getCanonicalPath(); + StringBuffer sb = new StringBuffer(path); + // reappend '*' to canonicalized filename (note that + // canonicalization may have removed trailing file + // separator, so we have to check for that, too) + if (!path.endsWith(File.separator) && + (appendFileSep || f.isDirectory())) { + sb.append(File.separatorChar); + } + sb.append('*'); + path = sb.toString(); + } else { + path = new File(path).getCanonicalPath(); + } + csUrl = new File(path).toURL(); + + if (cs instanceof SubjectCodeSource) { + SubjectCodeSource scs = (SubjectCodeSource)cs; + if (extractSignerCerts) { + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + csUrl, + getSignerCertificates(scs)); + } else { + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + csUrl, + scs.getCertificates()); + } + } else { + if (extractSignerCerts) { + canonCs = new CodeSource(csUrl, + getSignerCertificates(cs)); + } else { + canonCs = new CodeSource(csUrl, + cs.getCertificates()); + } + } + } catch (IOException ioe) { + // leave codesource as it is, unless we have to extract its + // signer certificates + if (extractSignerCerts) { + if (!(cs instanceof SubjectCodeSource)) { + canonCs = new CodeSource(cs.getLocation(), + getSignerCertificates(cs)); + } else { + SubjectCodeSource scs = (SubjectCodeSource)cs; + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + scs.getLocation(), + getSignerCertificates(scs)); + } + } + } + } else { + if (extractSignerCerts) { + if (!(cs instanceof SubjectCodeSource)) { + canonCs = new CodeSource(cs.getLocation(), + getSignerCertificates(cs)); + } else { + SubjectCodeSource scs = (SubjectCodeSource)cs; + canonCs = new SubjectCodeSource(scs.getSubject(), + scs.getPrincipals(), + scs.getLocation(), + getSignerCertificates(scs)); + } + } + } + return canonCs; + } + + /** + * Each entry in the policy configuration file is represented by a + * PolicyEntry object. <p> + * + * A PolicyEntry is a (CodeSource,Permission) pair. The + * CodeSource contains the (URL, PublicKey) that together identify + * where the Java bytecodes come from and who (if anyone) signed + * them. The URL could refer to localhost. The URL could also be + * null, meaning that this policy entry is given to all comers, as + * long as they match the signer field. The signer could be null, + * meaning the code is not signed. <p> + * + * The Permission contains the (Type, Name, Action) triplet. <p> + * + * For now, the Policy object retrieves the public key from the + * X.509 certificate on disk that corresponds to the signedBy + * alias specified in the Policy config file. For reasons of + * efficiency, the Policy object keeps a hashtable of certs already + * read in. This could be replaced by a secure internal key + * store. + * + * <p> + * For example, the entry + * <pre> + * permission java.io.File "/tmp", "read,write", + * signedBy "Duke"; + * </pre> + * is represented internally + * <pre> + * + * FilePermission f = new FilePermission("/tmp", "read,write"); + * PublicKey p = publickeys.get("Duke"); + * URL u = InetAddress.getLocalHost(); + * CodeBase c = new CodeBase( p, u ); + * pe = new PolicyEntry(f, c); + * </pre> + * + * @author Marianne Mueller + * @author Roland Schemers + * @see java.security.CodeSource + * @see java.security.Policy + * @see java.security.Permissions + * @see java.security.ProtectionDomain + */ + private static class PolicyEntry { + + CodeSource codesource; + Vector<Permission> permissions; + + /** + * Given a Permission and a CodeSource, create a policy entry. + * + * XXX Decide if/how to add validity fields and "purpose" fields to + * XXX policy entries + * + * @param cs the CodeSource, which encapsulates the URL and the public + * key attributes from the policy config file. Validity checks + * are performed on the public key before PolicyEntry is called. + * + */ + PolicyEntry(CodeSource cs) { + this.codesource = cs; + this.permissions = new Vector<Permission>(); + } + + /** + * add a Permission object to this entry. + */ + void add(Permission p) { + permissions.addElement(p); + } + + /** + * Return the CodeSource for this policy entry + */ + CodeSource getCodeSource() { + return this.codesource; + } + + @Override + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append(rb.getString("LPARAM")); + sb.append(getCodeSource()); + sb.append("\n"); + for (int j = 0; j < permissions.size(); j++) { + Permission p = permissions.elementAt(j); + sb.append(rb.getString("SPACE")); + sb.append(rb.getString("SPACE")); + sb.append(p); + sb.append(rb.getString("NEWLINE")); + } + sb.append(rb.getString("RPARAM")); + sb.append(rb.getString("NEWLINE")); + return sb.toString(); + } + + } +} + +@SuppressWarnings("deprecation") +class PolicyPermissions extends PermissionCollection { + + private static final long serialVersionUID = -1954188373270545523L; + + private CodeSource codesource; + private Permissions perms; + private AuthPolicyFile policy; + private boolean notInit; // have we pulled in the policy permissions yet? + private Vector<Permission> additionalPerms; + + PolicyPermissions(AuthPolicyFile policy, + CodeSource codesource) + { + this.codesource = codesource; + this.policy = policy; + this.perms = null; + this.notInit = true; + this.additionalPerms = null; + } + + @Override + public void add(Permission permission) { + if (isReadOnly()) + throw new SecurityException + (AuthPolicyFile.rb.getString + ("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection")); + + if (perms == null) { + if (additionalPerms == null) { + additionalPerms = new Vector<Permission>(); + } + additionalPerms.add(permission); + } else { + perms.add(permission); + } + } + + private synchronized void init() { + if (notInit) { + if (perms == null) { + perms = new Permissions(); + } + if (additionalPerms != null) { + Enumeration<Permission> e = additionalPerms.elements(); + while (e.hasMoreElements()) { + perms.add(e.nextElement()); + } + additionalPerms = null; + } + policy.getPermissions(perms, codesource); + notInit = false; + } + } + + @Override + public boolean implies(Permission permission) { + if (notInit) { + init(); + } + return perms.implies(permission); + } + + @Override + public Enumeration<Permission> elements() { + if (notInit) { + init(); + } + return perms.elements(); + } + + @Override + public String toString() { + if (notInit) { + init(); + } + return perms.toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/provider/SubjectCodeSource.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,401 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import java.net.URL; +import java.util.*; +import java.security.CodeSource; +import java.security.Principal; +import java.security.cert.Certificate; +import java.lang.reflect.Constructor; + +import javax.security.auth.Subject; +import sun.security.provider.PolicyParser.PrincipalEntry; + +/** + * <p> This <code>SubjectCodeSource</code> class contains + * a <code>URL</code>, signer certificates, and either a <code>Subject</code> + * (that represents the <code>Subject</code> in the current + * <code>AccessControlContext</code>), or a linked list of Principals + * (that represent a "subject" in a <code>Policy</code>). + * + */ +class SubjectCodeSource extends CodeSource implements java.io.Serializable { + + private static final long serialVersionUID = 6039418085604715275L; + + private static final java.util.ResourceBundle rb = + java.security.AccessController.doPrivileged + (new java.security.PrivilegedAction<java.util.ResourceBundle>() { + public java.util.ResourceBundle run() { + return (java.util.ResourceBundle.getBundle + ("sun.security.util.AuthResources")); + } + }); + + private Subject subject; + private LinkedList<PrincipalEntry> principals; + private static final Class[] PARAMS = { String.class }; + private static final sun.security.util.Debug debug = + sun.security.util.Debug.getInstance("auth", "\t[Auth Access]"); + private ClassLoader sysClassLoader; + + /** + * Creates a new <code>SubjectCodeSource</code> + * with the given <code>Subject</code>, principals, <code>URL</code>, + * and signers (Certificates). The <code>Subject</code> + * represents the <code>Subject</code> associated with the current + * <code>AccessControlContext</code>. + * The Principals are given as a <code>LinkedList</code> + * of <code>PolicyParser.PrincipalEntry</code> objects. + * Typically either a <code>Subject</code> will be provided, + * or a list of <code>principals</code> will be provided + * (not both). + * + * <p> + * + * @param subject the <code>Subject</code> associated with this + * <code>SubjectCodeSource</code> <p> + * + * @param url the <code>URL</code> associated with this + * <code>SubjectCodeSource</code> <p> + * + * @param certs the signers associated with this + * <code>SubjectCodeSource</code> <p> + */ + SubjectCodeSource(Subject subject, + LinkedList<PrincipalEntry> principals, + URL url, Certificate[] certs) { + + super(url, certs); + this.subject = subject; + this.principals = (principals == null ? + new LinkedList<PrincipalEntry>() : + new LinkedList<PrincipalEntry>(principals)); + sysClassLoader = java.security.AccessController.doPrivileged + (new java.security.PrivilegedAction<ClassLoader>() { + public ClassLoader run() { + return ClassLoader.getSystemClassLoader(); + } + }); + } + + /** + * Get the Principals associated with this <code>SubjectCodeSource</code>. + * The Principals are retrieved as a <code>LinkedList</code> + * of <code>PolicyParser.PrincipalEntry</code> objects. + * + * <p> + * + * @return the Principals associated with this + * <code>SubjectCodeSource</code> as a <code>LinkedList</code> + * of <code>PolicyParser.PrincipalEntry</code> objects. + */ + LinkedList<PrincipalEntry> getPrincipals() { + return principals; + } + + /** + * Get the <code>Subject</code> associated with this + * <code>SubjectCodeSource</code>. The <code>Subject</code> + * represents the <code>Subject</code> associated with the + * current <code>AccessControlContext</code>. + * + * <p> + * + * @return the <code>Subject</code> associated with this + * <code>SubjectCodeSource</code>. + */ + Subject getSubject() { + return subject; + } + + /** + * Returns true if this <code>SubjectCodeSource</code> object "implies" + * the specified <code>CodeSource</code>. + * More specifically, this method makes the following checks. + * If any fail, it returns false. If they all succeed, it returns true. + * + * <p> + * <ol> + * <li> The provided codesource must not be <code>null</code>. + * <li> codesource must be an instance of <code>SubjectCodeSource</code>. + * <li> super.implies(codesource) must return true. + * <li> for each principal in this codesource's principal list: + * <ol> + * <li> if the principal is an instanceof + * <code>Principal</code>, then the principal must + * imply the provided codesource's <code>Subject</code>. + * <li> if the principal is not an instanceof + * <code>Principal</code>, then the provided + * codesource's <code>Subject</code> must have an + * associated <code>Principal</code>, <i>P</i>, where + * P.getClass().getName equals principal.principalClass, + * and P.getName() equals principal.principalName. + * </ol> + * </ol> + * + * <p> + * + * @param codesource the <code>CodeSource</code> to compare against. + * + * @return true if this <code>SubjectCodeSource</code> implies the + * the specified <code>CodeSource</code>. + */ + public boolean implies(CodeSource codesource) { + + LinkedList<PrincipalEntry> subjectList = null; + + if (codesource == null || + !(codesource instanceof SubjectCodeSource) || + !(super.implies(codesource))) { + + if (debug != null) + debug.println("\tSubjectCodeSource.implies: FAILURE 1"); + return false; + } + + SubjectCodeSource that = (SubjectCodeSource)codesource; + + // if the principal list in the policy "implies" + // the Subject associated with the current AccessControlContext, + // then return true + + if (this.principals == null) { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: PASS 1"); + return true; + } + + if (that.getSubject() == null || + that.getSubject().getPrincipals().size() == 0) { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: FAILURE 2"); + return false; + } + + ListIterator<PrincipalEntry> li = this.principals.listIterator(0); + while (li.hasNext()) { + PrincipalEntry pppe = li.next(); + try { + + // use new Principal.implies method + + Class<?> pClass = Class.forName(pppe.principalClass, + true, sysClassLoader); + if (!Principal.class.isAssignableFrom(pClass)) { + // not the right subtype + throw new ClassCastException(pppe.principalClass + + " is not a Principal"); + } + Constructor<?> c = pClass.getConstructor(PARAMS); + Principal p = (Principal)c.newInstance(new Object[] { + pppe.principalName }); + + if (!p.implies(that.getSubject())) { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: FAILURE 3"); + return false; + } else { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: PASS 2"); + return true; + } + } catch (Exception e) { + + // simply compare Principals + + if (subjectList == null) { + + if (that.getSubject() == null) { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: " + + "FAILURE 4"); + return false; + } + Iterator<Principal> i = + that.getSubject().getPrincipals().iterator(); + + subjectList = new LinkedList<PrincipalEntry>(); + while (i.hasNext()) { + Principal p = i.next(); + PrincipalEntry spppe = new PrincipalEntry + (p.getClass().getName(), p.getName()); + subjectList.add(spppe); + } + } + + if (!subjectListImpliesPrincipalEntry(subjectList, pppe)) { + if (debug != null) + debug.println("\tSubjectCodeSource.implies: FAILURE 5"); + return false; + } + } + } + + if (debug != null) + debug.println("\tSubjectCodeSource.implies: PASS 3"); + return true; + } + + /** + * This method returns, true, if the provided <i>subjectList</i> + * "contains" the <code>Principal</code> specified + * in the provided <i>pppe</i> argument. + * + * Note that the provided <i>pppe</i> argument may have + * wildcards (*) for the <code>Principal</code> class and name, + * which need to be considered. + * + * <p> + * + * @param subjectList a list of PolicyParser.PrincipalEntry objects + * that correspond to all the Principals in the Subject currently + * on this thread's AccessControlContext. <p> + * + * @param pppe the Principals specified in a grant entry. + * + * @return true if the provided <i>subjectList</i> "contains" + * the <code>Principal</code> specified in the provided + * <i>pppe</i> argument. + */ + private boolean subjectListImpliesPrincipalEntry( + LinkedList<PrincipalEntry> subjectList, PrincipalEntry pppe) { + + ListIterator<PrincipalEntry> li = subjectList.listIterator(0); + while (li.hasNext()) { + PrincipalEntry listPppe = li.next(); + + if (pppe.getPrincipalClass().equals + (PrincipalEntry.WILDCARD_CLASS) || + pppe.getPrincipalClass().equals(listPppe.getPrincipalClass())) + { + if (pppe.getPrincipalName().equals + (PrincipalEntry.WILDCARD_NAME) || + pppe.getPrincipalName().equals(listPppe.getPrincipalName())) + return true; + } + } + return false; + } + + /** + * Tests for equality between the specified object and this + * object. Two <code>SubjectCodeSource</code> objects are considered equal + * if their locations are of identical value, if the two sets of + * Certificates are of identical values, and if the + * Subjects are equal, and if the PolicyParser.PrincipalEntry values + * are of identical values. It is not required that + * the Certificates or PolicyParser.PrincipalEntry values + * be in the same order. + * + * <p> + * + * @param obj the object to test for equality with this object. + * + * @return true if the objects are considered equal, false otherwise. + */ + public boolean equals(Object obj) { + + if (obj == this) + return true; + + if (super.equals(obj) == false) + return false; + + if (!(obj instanceof SubjectCodeSource)) + return false; + + SubjectCodeSource that = (SubjectCodeSource)obj; + + // the principal lists must match + try { + if (this.getSubject() != that.getSubject()) + return false; + } catch (SecurityException se) { + return false; + } + + if ((this.principals == null && that.principals != null) || + (this.principals != null && that.principals == null)) + return false; + + if (this.principals != null && that.principals != null) { + if (!this.principals.containsAll(that.principals) || + !that.principals.containsAll(this.principals)) + + return false; + } + + return true; + } + + /** + * Return a hashcode for this <code>SubjectCodeSource</code>. + * + * <p> + * + * @return a hashcode for this <code>SubjectCodeSource</code>. + */ + public int hashCode() { + return super.hashCode(); + } + + /** + * Return a String representation of this <code>SubjectCodeSource</code>. + * + * <p> + * + * @return a String representation of this <code>SubjectCodeSource</code>. + */ + public String toString() { + String returnMe = super.toString(); + if (getSubject() != null) { + if (debug != null) { + final Subject finalSubject = getSubject(); + returnMe = returnMe + "\n" + + java.security.AccessController.doPrivileged + (new java.security.PrivilegedAction<String>() { + public String run() { + return finalSubject.toString(); + } + }); + } else { + returnMe = returnMe + "\n" + getSubject().toString(); + } + } + if (principals != null) { + ListIterator<PrincipalEntry> li = principals.listIterator(); + while (li.hasNext()) { + PrincipalEntry pppe = li.next(); + returnMe = returnMe + rb.getString("NEWLINE") + + pppe.getPrincipalClass() + " " + + pppe.getPrincipalName(); + } + } + return returnMe; + } +}
--- a/src/share/classes/sun/security/rsa/RSAPadding.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/security/rsa/RSAPadding.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -458,7 +458,7 @@ private void mgf1(byte[] seed, int seedOfs, int seedLen, byte[] out, int outOfs, int maskLen) throws BadPaddingException { byte[] C = new byte[4]; // 32 bit counter - byte[] digest = new byte[20]; // 20 bytes is length of SHA-1 digest + byte[] digest = new byte[mgfMd.getDigestLength()]; while (maskLen > 0) { mgfMd.update(seed, seedOfs, seedLen); mgfMd.update(C);
--- a/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -57,7 +57,8 @@ private final KerberosClientKeyExchange impl = createImpl(); private KerberosClientKeyExchange createImpl() { - if (getClass() == KerberosClientKeyExchange.class) { + if (implClass != null && + getClass() == KerberosClientKeyExchange.class) { try { return (KerberosClientKeyExchange)implClass.newInstance(); } catch (InstantiationException e) { @@ -69,8 +70,11 @@ return null; } - public KerberosClientKeyExchange() { - // empty + // This constructor will be called when constructing an instance of its + // subclass -- KerberosClientKeyExchangeImpl. Please won't check the + // value of impl variable in this constructor. + protected KerberosClientKeyExchange() { + // please won't check the value of impl variable } public KerberosClientKeyExchange(String serverName, boolean isLoopback, @@ -85,8 +89,9 @@ } public KerberosClientKeyExchange(ProtocolVersion protocolVersion, - ProtocolVersion clientVersion, SecureRandom rand, - HandshakeInStream input, AccessControlContext acc, Object serverKeys) throws IOException { + ProtocolVersion clientVersion, SecureRandom rand, + HandshakeInStream input, AccessControlContext acc, + Object serverKeys) throws IOException { if (impl != null) { init(protocolVersion, clientVersion, rand, input, acc, serverKeys); @@ -101,7 +106,7 @@ } @Override - public int messageLength() { + public int messageLength() { return impl.messageLength(); } @@ -125,11 +130,13 @@ } public void init(ProtocolVersion protocolVersion, - ProtocolVersion clientVersion, SecureRandom rand, - HandshakeInStream input, AccessControlContext acc, Object ServiceCreds) throws IOException { + ProtocolVersion clientVersion, SecureRandom rand, + HandshakeInStream input, AccessControlContext acc, + Object ServiceCreds) throws IOException { if (impl != null) { - impl.init(protocolVersion, clientVersion, rand, input, acc, ServiceCreds); + impl.init(protocolVersion, clientVersion, + rand, input, acc, ServiceCreds); } }
--- a/src/share/classes/sun/tools/jconsole/ConnectDialog.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/ConnectDialog.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -268,8 +268,13 @@ public void revalidate() { // Adjust some colors + Color disabledForeground = UIManager.getColor("Label.disabledForeground"); + if (disabledForeground == null) { + // fall back for Nimbus that doesn't support 'Label.disabledForeground' + disabledForeground = UIManager.getColor("Label.disabledText"); + } hintTextColor = - ensureContrast(UIManager.getColor("Label.disabledForeground"), + ensureContrast(disabledForeground, UIManager.getColor("Panel.background")); disabledTableCellColor = ensureContrast(new Color(0x808080),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/tools/jconsole/ExceptionSafePlugin.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.tools.jconsole; + +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +import com.sun.tools.jconsole.JConsolePlugin; + +/** + * Proxy that shields GUI from plug-in exceptions. + * + */ +final class ExceptionSafePlugin extends JConsolePlugin { + + private static boolean ignoreExceptions; + private final JConsolePlugin plugin; + + public ExceptionSafePlugin(JConsolePlugin plugin) { + this.plugin = plugin; + } + + @Override + public Map<String, JPanel> getTabs() { + try { + return plugin.getTabs(); + } catch (RuntimeException e) { + handleException(e); + } + return new HashMap<>(); + } + + @Override + public SwingWorker<?, ?> newSwingWorker() { + try { + return plugin.newSwingWorker(); + } catch (RuntimeException e) { + handleException(e); + } + return null; + } + + @Override + public void dispose() { + try { + plugin.dispose(); + } catch (RuntimeException e) { + handleException(e); + } + } + + public void executeSwingWorker(SwingWorker<?, ?> sw) { + try { + sw.execute(); + } catch (RuntimeException e) { + handleException(e); + } + } + + private void handleException(Exception e) { + if (JConsole.isDebug()) { + System.err.println("Plug-in exception:"); + e.printStackTrace(); + } else { + if (!ignoreExceptions) { + showExceptionDialog(e); + } + } + } + + private void showExceptionDialog(Exception e) { + Object[] buttonTexts = { + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_OK, + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT, + Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE + }; + + String message = String.format( + Messages.PLUGIN_EXCEPTION_DIALOG_MESSAGE, + plugin.getClass().getSimpleName(), + String.valueOf(e.getMessage()) + ); + + int buttonIndex = JOptionPane.showOptionDialog( + null, + message, + Messages.PLUGIN_EXCEPTION_DIALOG_TITLE, + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.ERROR_MESSAGE, + null, + buttonTexts, + buttonTexts[0] + ); + + if (buttonIndex == 1) { + System.exit(0); + } + ignoreExceptions = buttonIndex == 2; + } +}
--- a/src/share/classes/sun/tools/jconsole/JConsole.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/JConsole.java Tue Aug 27 12:27:31 2013 -0400 @@ -858,6 +858,10 @@ try { updateInterval = Integer.parseInt(arg.substring(10)) * 1000; + if (updateInterval <= 0) { + usage(); + return; + } } catch (NumberFormatException ex) { usage(); return;
--- a/src/share/classes/sun/tools/jconsole/MemoryTab.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/MemoryTab.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -228,6 +228,7 @@ if (ev.getStateChange() == ItemEvent.SELECTED) { Plotter plotter = (Plotter)plotterChoice.getSelectedItem(); plotterPanel.setPlotter(plotter); + plotterPanel.repaint(); } }
--- a/src/share/classes/sun/tools/jconsole/Messages.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/Messages.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,6 @@ public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME; public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE; public static String HELP_ABOUT_DIALOG_TITLE; - public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK; public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL; public static String HELP_MENU_ABOUT_TITLE; public static String HELP_MENU_USER_GUIDE_TITLE; @@ -240,6 +239,11 @@ public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA; public static String PLOTTER_SAVE_AS_MENU_ITEM; public static String PLOTTER_TIME_RANGE_MENU; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE; + public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_OK; + public static String PLUGIN_EXCEPTION_DIALOG_MESSAGE; + public static String PLUGIN_EXCEPTION_DIALOG_TITLE; public static String PROBLEM_ADDING_LISTENER; public static String PROBLEM_DISPLAYING_MBEAN; public static String PROBLEM_INVOKING; @@ -267,6 +271,7 @@ public static String THREADS; public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME; public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME; + public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE; public static String THRESHOLD; public static String TILE; public static String TIME_RANGE_COLON;
--- a/src/share/classes/sun/tools/jconsole/Plotter.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/Plotter.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -337,6 +337,13 @@ public void paintComponent(Graphics g) { super.paintComponent(g); + int width = getWidth()-rightMargin-leftMargin-10; + int height = getHeight()-topMargin-bottomMargin; + if (width <= 0 || height <= 0) { + // not enough room to paint anything + return; + } + Color oldColor = g.getColor(); Font oldFont = g.getFont(); Color fg = getForeground();
--- a/src/share/classes/sun/tools/jconsole/ThreadTab.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/ThreadTab.java Tue Aug 27 12:27:31 2013 -0400 @@ -595,6 +595,8 @@ setBorder(thinEmptyBorder); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + textArea.setText(Messages.THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE); addListSelectionListener(ThreadTab.this); setCellRenderer(new DefaultListCellRenderer() { public Component getListCellRendererComponent(JList<?> list, Object value, int index,
--- a/src/share/classes/sun/tools/jconsole/VMPanel.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/VMPanel.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -71,7 +71,7 @@ // Each VMPanel has its own instance of the JConsolePlugin // A map of JConsolePlugin to the previous SwingWorker - private Map<JConsolePlugin, SwingWorker<?, ?>> plugins = null; + private Map<ExceptionSafePlugin, SwingWorker<?, ?>> plugins = null; private boolean pluginTabsAdded = false; // Update these only on the EDT @@ -107,10 +107,10 @@ } } - plugins = new LinkedHashMap<JConsolePlugin, SwingWorker<?, ?>>(); + plugins = new LinkedHashMap<ExceptionSafePlugin, SwingWorker<?, ?>>(); for (JConsolePlugin p : JConsole.getPlugins()) { p.setContext(proxyClient); - plugins.put(p, null); + plugins.put(new ExceptionSafePlugin(p), null); } Utilities.updateTransparency(this); @@ -153,9 +153,11 @@ // in order to reserve space for the connect toggle. public void setUI(TabbedPaneUI ui) { Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); - insets = (Insets) insets.clone(); - insets.right += connectedIcon24.getIconWidth() + 8; - UIManager.put("TabbedPane.tabAreaInsets", insets); + if (insets != null) { + insets = (Insets) insets.clone(); + insets.right += connectedIcon24.getIconWidth() + 8; + UIManager.put("TabbedPane.tabAreaInsets", insets); + } super.setUI(ui); } @@ -566,7 +568,7 @@ } // plugin GUI update - for (JConsolePlugin p : plugins.keySet()) { + for (ExceptionSafePlugin p : plugins.keySet()) { SwingWorker<?, ?> sw = p.newSwingWorker(); SwingWorker<?, ?> prevSW = plugins.get(p); // schedule SwingWorker to run only if the previous @@ -575,7 +577,7 @@ if (sw == null || sw.getState() == SwingWorker.StateValue.PENDING) { plugins.put(p, sw); if (sw != null) { - sw.execute(); + p.executeSwingWorker(sw); } } }
--- a/src/share/classes/sun/tools/jconsole/resources/messages.properties Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/resources/messages.properties Tue Aug 27 12:27:31 2013 -0400 @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole HELP_ABOUT_DIALOG_TITLE=JConsole: About -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole &User Guide:<br>{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=&About JConsole HELP_MENU_USER_GUIDE_TITLE=Online &User Guide @@ -137,14 +136,14 @@ MBEANS=MBeans MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=&Clear MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=Clear notifications -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Navigation {0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Navigation +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Data Navigation {0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Data Navigation MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=&Refresh MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=Refresh attributes MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=&Subscribe MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Start listening for notifications -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Navigation {0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Navigation +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Data Navigation {0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Data Navigation MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=&Unsubscribe MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Stop listening for notifications MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in: @@ -198,6 +197,11 @@ PLOTTER_ACCESSIBLE_NAME_NO_DATA=No data plotted. PLOTTER_SAVE_AS_MENU_ITEM=Save data &as... PLOTTER_TIME_RANGE_MENU=&Time Range +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=Exit +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=Ignore +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=OK +PLUGIN_EXCEPTION_DIALOG_MESSAGE=An unexpected exception has occurred in %s:\n\n%s\n\nStart with -debug for details. Ignore will suppress further exceptions. +PLUGIN_EXCEPTION_DIALOG_TITLE=Plug-in exception PROBLEM_ADDING_LISTENER=Problem adding listener PROBLEM_DISPLAYING_MBEAN=Problem displaying MBean PROBLEM_INVOKING=Problem invoking @@ -225,6 +229,7 @@ THREADS=Threads THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads. +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[No thread selected] THRESHOLD=Threshold TILE=&Tile TIME_RANGE_COLON=&Time Range:
--- a/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Tue Aug 27 12:27:31 2013 -0400 @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066 HELP_ABOUT_DIALOG_TITLE=JConsole: \u8A73\u7D30 -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U):<br>{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A) HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U)
--- a/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Tue Aug 27 12:27:31 2013 -0400 @@ -104,7 +104,6 @@ HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u62A5\u5934\u56FE HELP_ABOUT_DIALOG_MASTHEAD_TITLE=\u5173\u4E8E JConsole HELP_ABOUT_DIALOG_TITLE=JConsole: \u5173\u4E8E -HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole \u7528\u6237\u6307\u5357(&U):<br>{0} HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html HELP_MENU_ABOUT_TITLE=\u5173\u4E8E JConsole(&A) HELP_MENU_USER_GUIDE_TITLE=\u8054\u673A\u7528\u6237\u6307\u5357(&U)
--- a/src/share/native/java/io/RandomAccessFile.c Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/native/java/io/RandomAccessFile.c Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -123,7 +123,7 @@ } JNIEXPORT void JNICALL -Java_java_io_RandomAccessFile_seek(JNIEnv *env, +Java_java_io_RandomAccessFile_seek0(JNIEnv *env, jobject this, jlong pos) { FD fd;
--- a/src/share/native/sun/font/sunFont.c Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/native/sun/font/sunFont.c Tue Aug 27 12:27:31 2013 -0400 @@ -71,13 +71,17 @@ void initLCDGammaTables(); /* placeholder for extern variable */ +static int initialisedFontIDs = 0; FontManagerNativeIDs sunFontIDs; -JNIEXPORT void JNICALL -Java_sun_font_SunFontManager_initIDs - (JNIEnv *env, jclass cls) { +static void initFontIDs(JNIEnv *env) { + + jclass tmpClass; - jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"); + if (initialisedFontIDs) { + return; + } + tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"); sunFontIDs.ttReadBlockMID = (*env)->GetMethodID(env, tmpClass, "readBlock", "(Ljava/nio/ByteBuffer;II)I"); @@ -173,9 +177,20 @@ (*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z"); initLCDGammaTables(); + + initialisedFontIDs = 1; } -JNIEXPORT FontManagerNativeIDs getSunFontIDs() { +JNIEXPORT void JNICALL +Java_sun_font_SunFontManager_initIDs + (JNIEnv *env, jclass cls) { + + initFontIDs(env); +} + +JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv *env) { + + initFontIDs(env); return sunFontIDs; }
--- a/src/share/native/sun/font/sunfontids.h Tue Aug 27 12:04:32 2013 -0400 +++ b/src/share/native/sun/font/sunfontids.h Tue Aug 27 12:27:31 2013 -0400 @@ -84,7 +84,7 @@ /* Note: we share variable in the context of fontmanager lib but we need access method to use it from separate rasterizer lib */ extern FontManagerNativeIDs sunFontIDs; -JNIEXPORT FontManagerNativeIDs getSunFontIDs(); +JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv* env); #ifdef __cplusplus }
--- a/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue Aug 27 12:04:32 2013 -0400 +++ b/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue Aug 27 12:27:31 2013 -0400 @@ -245,7 +245,7 @@ continue; } if ((defaultPrintService != null) - && printers[p].equals(defaultPrintService.getName())) { + && printers[p].equals(getPrinterDestName(defaultPrintService))) { printerList.add(defaultPrintService); defaultIndex = printerList.size() - 1; } else { @@ -270,11 +270,12 @@ } else { int j; for (j=0; j<printServices.length; j++) { - if ((printServices[j] != null) && - (printers[p].equals(printServices[j].getName()))) { - printerList.add(printServices[j]); - printServices[j] = null; - break; + if (printServices[j] != null) { + if (printers[p].equals(getPrinterDestName(printServices[j]))) { + printerList.add(printServices[j]); + printServices[j] = null; + break; + } } } @@ -360,6 +361,17 @@ return true; } + /* + * Gets the printer name compatible with the list of printers returned by + * the system when we query default or all the available printers. + */ + private String getPrinterDestName(PrintService ps) { + if (isMac()) { + return ((IPPPrintService)ps).getDest(); + } + return ps.getName(); + } + /* On a network with many (hundreds) of network printers, it * can save several seconds if you know all you want is a particular * printer, to ask for that printer rather than retrieving all printers. @@ -369,10 +381,12 @@ if (name == null || name.equals("") || !checkPrinterName(name)) { return null; } - /* check is all printers are already available */ + /* check if all printers are already available */ if (printServices != null) { for (PrintService printService : printServices) { - if (printService.getName().equals(name)) { + PrinterName printerName = + (PrinterName)printService.getAttribute(PrinterName.class); + if (printerName.getValue().equals(name)) { return printService; } } @@ -567,7 +581,7 @@ defaultPrintService = null; if (printServices != null) { for (int j=0; j<printServices.length; j++) { - if (defaultPrinter.equals(printServices[j].getName())) { + if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) { defaultPrintService = printServices[j]; break; }
--- a/src/solaris/native/sun/awt/awt_DrawingSurface.c Tue Aug 27 12:04:32 2013 -0400 +++ b/src/solaris/native/sun/awt/awt_DrawingSurface.c Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -346,13 +346,19 @@ awt_GetComponent(JNIEnv* env, void* platformInfo) { Window window = (Window)platformInfo; - Widget widget = NULL; jobject peer = NULL; jobject target = NULL; AWT_LOCK(); - target = (*env)->GetObjectField(env, peer, targetID); + if (window != None) { + peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", + "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l; + } + if ((peer != NULL) && + (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) { + target = (*env)->GetObjectField(env, peer, targetID); + } if (target == NULL) { JNU_ThrowNullPointerException(env, "NullPointerException"); @@ -360,7 +366,6 @@ return (jobject)NULL; } - AWT_UNLOCK(); return target;
--- a/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c Tue Aug 27 12:04:32 2013 -0400 +++ b/src/windows/native/sun/java2d/opengl/WGLSurfaceData.c Tue Aug 27 12:27:31 2013 -0400 @@ -67,12 +67,13 @@ J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_initOps"); - if (oglsdo == NULL) { - JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); + if (wglsdo == NULL) { + JNU_ThrowOutOfMemoryError(env, "creating native wgl ops"); return; } - if (wglsdo == NULL) { - JNU_ThrowOutOfMemoryError(env, "creating native wgl ops"); + if (oglsdo == NULL) { + free(wglsdo); + JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); return; }
--- a/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Tue Aug 27 12:04:32 2013 -0400 +++ b/src/windows/native/sun/tools/attach/WindowsVirtualMachine.c Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -91,7 +91,7 @@ * Code copied to target process */ #pragma check_stack (off) -static DWORD WINAPI thread_func(DataBlock *pData) +DWORD WINAPI jvm_attach_thread_func(DataBlock *pData) { HINSTANCE h; EnqueueOperationFunc addr; @@ -117,8 +117,8 @@ } } -/* This function marks the end of thread_func. */ -static void thread_end (void) { +/* This function marks the end of jvm_attach_thread_func. */ +void jvm_attach_thread_func_end (void) { } #pragma check_stack @@ -152,10 +152,10 @@ DWORD len; jbyteArray array; - len = (DWORD)((LPBYTE) thread_end - (LPBYTE) thread_func); + len = (DWORD)((LPBYTE) jvm_attach_thread_func_end - (LPBYTE) jvm_attach_thread_func); array= (*env)->NewByteArray(env, (jsize)len); if (array != NULL) { - (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&thread_func); + (*env)->SetByteArrayRegion(env, array, 0, (jint)len, (jbyte*)&jvm_attach_thread_func); } return array; }
--- a/src/windows/native/sun/windows/awt_Cursor.cpp Tue Aug 27 12:04:32 2013 -0400 +++ b/src/windows/native/sun/windows/awt_Cursor.cpp Tue Aug 27 12:27:31 2013 -0400 @@ -391,9 +391,16 @@ DASSERT(hCursor); - AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot, - yHotSpot, nW, nH, nSS, cols, - (BYTE *)andMaskPtr))); + try { + AwtCursor::setPData(self, ptr_to_jlong(new AwtCursor(env, hCursor, self, xHotSpot, + yHotSpot, nW, nH, nSS, cols, + (BYTE *)andMaskPtr))); + } catch (...) { + if (cols) { + delete[] cols; + } + throw; + } CATCH_BAD_ALLOC; }
--- a/src/windows/native/sun/windows/awt_Font.cpp Tue Aug 27 12:04:32 2013 -0400 +++ b/src/windows/native/sun/windows/awt_Font.cpp Tue Aug 27 12:27:31 2013 -0400 @@ -510,6 +510,11 @@ jobject font = env->GetObjectField(fontMetrics, AwtFont::fontID); AwtFont* awtFont = AwtFont::GetFont(env, font); + if (!awtFont) { + /* failed to get font */ + return; + } + HDC hDC = ::GetDC(0); DASSERT(hDC != NULL);
--- a/test/ProblemList.txt Tue Aug 27 12:04:32 2013 -0400 +++ b/test/ProblemList.txt Tue Aug 27 12:27:31 2013 -0400 @@ -208,7 +208,7 @@ # jdk_io # 7160013 -java/io/File/MaxPathLength.java windows-all +#java/io/File/MaxPathLength.java windows-all ############################################################################ @@ -289,9 +289,6 @@ sun/security/krb5/auto/BadKdc3.java solaris-sparcv9 sun/security/krb5/auto/BadKdc4.java solaris-sparcv9 -# 8022896 -com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java generic-all - ############################################################################ # jdk_sound @@ -339,12 +336,6 @@ # Filed 6653793 com/sun/jdi/RedefineCrossEvent.java generic-all -# Filed 6987312 -com/sun/jdi/DoubleAgentTest.java generic-all - -# Filed 7020857 -com/sun/jdi/FieldWatchpoints.java generic-all - # Filed 6402201 com/sun/jdi/ProcessAttachTest.sh generic-all
--- a/test/TEST.ROOT Tue Aug 27 12:04:32 2013 -0400 +++ b/test/TEST.ROOT Tue Aug 27 12:27:31 2013 -0400 @@ -9,3 +9,6 @@ # Tests that cannot run concurrently exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi + +# Group definitions +groups=TEST.groups [closed/TEST.groups]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/TEST.groups Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,214 @@ +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +jdk_lang = \ + java/lang \ + -java/lang/management \ + -java/lang/instrument \ + sun/invoke \ + sun/misc \ + sun/reflect \ + vm + +jdk_util = \ + java/util \ + sun/util + +jdk_math = \ + java/math + +jdk_io = \ + java/io + +jdk_nio = \ + java/nio \ + sun/nio + +jdk_net = \ + java/net \ + com/sun/net \ + com/oracle/net \ + sun/net + +jdk_time = \ + java/time + +jdk_rmi = \ + java/rmi \ + javax/rmi/ssl \ + sun/rmi + +jdk_security1 = \ + java/security + +jdk_security2 = \ + javax/crypto \ + javax/xml/crypto \ + com/sun/crypto + +jdk_security3 = \ + javax/security \ + com/sun/security \ + com/sun/org/apache/xml/internal/security \ + com/oracle/security \ + sun/security \ + lib/security + +jdk_security = \ + :jdk_security1 \ + :jdk_security2 \ + :jdk_security3 + +jdk_text = \ + java/text \ + sun/text + +jdk_management = \ + java/lang/management \ + com/sun/management \ + sun/management + +jdk_instrument = \ + java/lang/instrument + +jdk_jmx = \ + javax/management \ + com/sun/jmx + +jdk_jdi = \ + com/sun/jdi + +# +# Tool (and tool API) tests are split into core and svc groups +# +core_tools = \ + tools \ + com/sun/tools/extcheck \ + sun/tools/java \ + sun/tools/native2ascii \ + sun/tools/jrunscript + +svc_tools = \ + com/sun/tools/attach \ + com/sun/tracing \ + sun/tools \ + -sun/tools/java \ + -sun/tools/native2ascii \ + -sun/tools/jrunscript \ + sun/jvmstat \ + demo/jvmti + +jdk_tools = \ + :core_tools \ + :svc_tools + +# +# Catch-all for other areas with a small number of tests +# +jdk_other = \ + java/sql \ + javax/sql \ + javax/naming \ + javax/script \ + javax/smartcardio \ + javax/xml \ + -javax/xml/crypto \ + jdk/asm \ + jdk/lambda \ + com/sun/jndi \ + com/sun/corba \ + lib/testlibrary \ + demo/zipfs \ + sample + +# +# SCTP is its own group as it is highly sensitive to kernel/network config +# +jdk_sctp = \ + com/sun/nio/sctp + + +# +# core group to run all core area tests +# +jdk_core = \ + :jdk_lang \ + :jdk_util \ + :jdk_math \ + :jdk_io \ + :jdk_nio \ + :jdk_net \ + :jdk_rmi \ + :jdk_time \ + :jdk_security \ + :jdk_text \ + :core_tools \ + :jdk_other + +# +# svc group to run all serviceability area tests +# +jdk_svc = \ + :jdk_management \ + :jdk_instrument \ + :jdk_jmx \ + :jdk_jdi \ + :svc_tools + +############################# + +# +# Client area groups +# + +jdk_awt = \ + java/awt \ + com/sun/awt \ + com/apple/eawt \ + sun/awt + +jdk_2d = \ + javax/print \ + sun/pisces \ + sun/java2d + +jdk_beans = \ + java/beans + +jdk_swing = \ + javax/accessibility \ + javax/swing \ + com/sun/java/swing + +jdk_sound = \ + javax/sound + +jdk_imageio = \ + javax/imageio + +jdk_desktop = \ + :jdk_awt \ + :jdk_2d \ + :jdk_beans \ + :jdk_swing \ + :jdk_sound \ + :jdk_imageio
--- a/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/com/sun/crypto/provider/Cipher/RSA/TestOAEPPadding.java Tue Aug 27 12:27:31 2013 -0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 8020081 + * @bug 8020081 8022669 * @summary encryption/decryption test for using OAEPPadding with * OAEPParameterSpec specified and not specified during a Cipher.init(). * @author Anthony Scarpino @@ -62,20 +62,74 @@ publicKey = (RSAPublicKey)kp.getPublic(); // Test using a spec with each digest algorithm case + // MD5 test(new OAEPParameterSpec("MD5", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("MD5", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA1 test(new OAEPParameterSpec("SHA1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA1", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); // For default OAEPParameterSpec case (SHA1) test(null); + // SHA-224 test(new OAEPParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-224", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-256 test(new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-384 test(new OAEPParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-384", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); + // SHA-512 test(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA224, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA384, PSource.PSpecified.DEFAULT)); + test(new OAEPParameterSpec("SHA-512", "MGF1", + MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT)); if (failed) { throw new Exception("Test failed"); } @@ -149,9 +203,16 @@ private static void testEncryptDecrypt(OAEPParameterSpec spec, int dataLength) throws Exception { - System.out.println("Testing OAEP with hash " + - ((spec != null) ? spec.getDigestAlgorithm() : "Default") + - ", " + dataLength + " bytes"); + + System.out.print("Testing OAEP with hash "); + if (spec != null) { + System.out.print(spec.getDigestAlgorithm() + " and MGF " + + ((MGF1ParameterSpec)spec.getMGFParameters()). + getDigestAlgorithm()); + } else { + System.out.print("Default"); + } + System.out.println(", " + dataLength + " bytes"); Cipher c = Cipher.getInstance("RSA/ECB/OAEPPadding", cp); if (spec != null) {
--- a/test/com/sun/jdi/sde/TemperatureTableTest.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/com/sun/jdi/sde/TemperatureTableTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -7,7 +7,7 @@ * @author Robert Field * * @library .. - * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE + * @run build TestScaffold VMConnection TargetListener TargetAdapter InstallSDE HelloWorld * @run compile TemperatureTableTest.java * @run compile -g TemperatureTableServlet.java * @run main TemperatureTableTest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Focus/8013611/JDK8013611.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8013611 + @summary Tests showing a modal dialog with requesting focus in frame. + @author Anton.Tarasov: area=awt.focus + @library ../../regtesthelpers + @build Util + @run main JDK8013611 +*/ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import test.java.awt.regtesthelpers.Util; + +import java.awt.*; + +public class JDK8013611 extends JFrame { + static JTextField textField = new JTextField("text"); + static JButton button1 = new JButton("button1"); + static JButton button2 = new JButton("button2"); + static Robot robot; + + static JDialog dialog; + static JButton button3 = new JButton("button3"); + + public static void main(String[] args) { + robot = Util.createRobot(); + + JDK8013611 frame = new JDK8013611(); + frame.setLayout(new FlowLayout()); + frame.add(textField); + frame.add(button1); + frame.add(button2); + frame.pack(); + + dialog = new JDialog(frame, true); + dialog.add(button3); + dialog.pack(); + + textField.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + dialog.setVisible(true); + } + }); + + button1.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + button2.requestFocusInWindow(); + } + }); + + frame.setVisible(true); + + frame.test(); + } + + public void test() { + if (!testFocused(textField)) { + Util.clickOnComp(textField, robot); + if (!testFocused(textField)) { + throw new RuntimeException("Error: couldn't focus " + textField); + } + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + + if (!testFocused(button3)) { + throw new RuntimeException("Test failed: dialog didn't get focus!"); + } + + System.out.println("Test passed."); + } + + boolean testFocused(Component c) { + for (int i=0; i<10; i++) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == c) { + return true; + } + Util.waitForIdle(robot); + } + return false; + } +}
--- a/test/java/awt/Graphics2D/Test8004859/Test8004859.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/awt/Graphics2D/Test8004859/Test8004859.java Tue Aug 27 12:27:31 2013 -0400 @@ -37,7 +37,7 @@ */ public final class Test8004859 { - private static Shape[] clips = {new Rectangle(0, 0, 1, 1), new Rectangle( + private static Shape[] clips = {new Rectangle(0, 0, -1, -1), new Rectangle( 100, 100, -100, -100)}; private static boolean status = true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/io/BufferedInputStream/LargeCopyWithMark.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 7129312 + * @summary BufferedInputStream calculates negative array size with large + * streams and mark + * @library /lib/testlibrary + * @run main/othervm LargeCopyWithMark + */ + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import static jdk.testlibrary.ProcessTools.*; + + +public class LargeCopyWithMark { + + public static void main(String[] args) throws Exception { + if (! System.getProperty("os.arch").contains("64")) { + System.out.println("Test runs on 64 bit platforms"); + return; + } + ProcessBuilder pb = createJavaProcessBuilder("-Xmx4G", + "-ea:LargeCopyWithMark$Child", + "LargeCopyWithMark$Child"); + int res = pb.inheritIO().start().waitFor(); + if (res != 0) { + throw new AssertionError("Test failed: exit code = " + res); + } + } + + public static class Child { + static final int BUFF_SIZE = 8192; + static final int BIS_BUFF_SIZE = Integer.MAX_VALUE / 2 + 100; + static final long BYTES_TO_COPY = 2L * Integer.MAX_VALUE; + + static { + assert BIS_BUFF_SIZE * 2 < 0 : "doubling must overflow"; + } + + public static void main(String[] args) throws Exception { + byte[] buff = new byte[BUFF_SIZE]; + + try (InputStream myis = new MyInputStream(BYTES_TO_COPY); + InputStream bis = new BufferedInputStream(myis, BIS_BUFF_SIZE); + OutputStream myos = new MyOutputStream()) { + + // will require a buffer bigger than BIS_BUFF_SIZE + bis.mark(BIS_BUFF_SIZE + 100); + + for (;;) { + int count = bis.read(buff, 0, BUFF_SIZE); + if (count == -1) + break; + myos.write(buff, 0, count); + } + } catch (java.lang.NegativeArraySizeException e) { + e.printStackTrace(); + System.exit(11); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} + +class MyInputStream extends InputStream { + private long bytesLeft; + public MyInputStream(long bytesLeft) { + this.bytesLeft = bytesLeft; + } + @Override public int read() throws IOException { + return 0; + } + @Override public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + @Override public int read(byte[] b, int off, int len) throws IOException { + if (bytesLeft <= 0) + return -1; + long result = Math.min(bytesLeft, (long)len); + bytesLeft -= result; + return (int)result; + } + @Override public int available() throws IOException { + return (bytesLeft > 0) ? 1 : 0; + } +} + +class MyOutputStream extends OutputStream { + @Override public void write(int b) throws IOException {} + @Override public void write(byte[] b) throws IOException {} + @Override public void write(byte[] b, int off, int len) throws IOException {} +}
--- a/test/java/io/File/MaxPathLength.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/io/File/MaxPathLength.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -27,6 +27,7 @@ */ import java.io.*; +import java.nio.file.Files; public class MaxPathLength { private static String sep = File.separator; @@ -87,10 +88,8 @@ System.err.println("Warning: Test directory structure exists already!"); return; } - boolean couldMakeTestDirectory = dirFile.mkdirs(); - if (!couldMakeTestDirectory) { - throw new RuntimeException ("Could not create test directory structure"); - } + Files.createDirectories(dirFile.toPath()); + try { if (tryAbsolute) dirFile = new File(dirFile.getCanonicalPath());
--- a/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -28,6 +28,9 @@ */ import java.lang.annotation.Retention; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; @@ -66,17 +69,6 @@ } } - static void dumpState(Task task) { - System.err.println( - "Task[" + task.getName() + "].state: " + - task.getState() + " ..." - ); - for (StackTraceElement ste : task.getStackTrace()) { - System.err.println("\tat " + ste); - } - System.err.println(); - } - public static void main(String[] args) throws Exception { CountDownLatch prepareLatch = new CountDownLatch(2); AtomicInteger goLatch = new AtomicInteger(1); @@ -88,18 +80,22 @@ prepareLatch.await(); // let them go goLatch.set(0); - // attempt to join them - taskA.join(5000L); - taskB.join(5000L); - - if (taskA.isAlive() || taskB.isAlive()) { - dumpState(taskA); - dumpState(taskB); - throw new IllegalStateException( - taskA.getState() == Thread.State.BLOCKED && - taskB.getState() == Thread.State.BLOCKED - ? "deadlock detected" - : "unexpected condition"); + // obtain ThreadMXBean + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + // wait for threads to finish or dead-lock + while (taskA.isAlive() || taskB.isAlive()) { + // attempt to join threads + taskA.join(500L); + taskB.join(500L); + // detect dead-lock + long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads(); + if (deadlockedIds != null && deadlockedIds.length > 0) { + StringBuilder sb = new StringBuilder("deadlock detected:\n\n"); + for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) { + sb.append(ti); + } + throw new IllegalStateException(sb.toString()); + } } } }
--- a/test/java/lang/annotation/TypeAnnotationReflection.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/lang/annotation/TypeAnnotationReflection.java Tue Aug 27 12:27:31 2013 -0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 8004698 8007073 + * @bug 8004698 8007073 8022343 * @summary Unit test for type annotations */ @@ -58,7 +58,7 @@ } private static void testSuper() throws Exception { - check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0); + check(Object.class.getAnnotatedSuperclass() == null); check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0); AnnotatedType a;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8022343 + * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so + */ + +public class GetAnnotatedSuperclass { + private static final Class<?>[] testData = { + Object.class, + If.class, + Object[].class, + void.class, + int.class, + }; + + public static void main(String[] args) throws Exception { + int failed = 0; + for (Class<?> toTest : testData) { + Object res = toTest.getAnnotatedSuperclass(); + + if (res != null) { + failed++; + System.out.println(toTest + ".getAnnotatedSuperclass() returns: " + + res + ", should be null"); + } + } + + if (failed != 0) + throw new RuntimeException("Test failed, check log for details"); + } + + interface If {} +}
--- a/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Tue Aug 27 12:27:31 2013 -0400 @@ -33,10 +33,10 @@ * @author Mandy Chung * * @build ResetPeakMemoryUsage MemoryUtil - * @run main/othervm -XX:+UseSerialGC -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage - * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage + * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage */ import java.lang.management.*;
--- a/test/java/math/BigDecimal/IntegralDivisionTests.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/math/BigDecimal/IntegralDivisionTests.java Tue Aug 27 12:27:31 2013 -0400 @@ -22,7 +22,7 @@ */ /* * @test - * @bug 4904082 4917089 6337226 + * @bug 4904082 4917089 6337226 6378503 * @summary Tests that integral division and related methods return the proper result and scale. * @author Joseph D. Darcy */ @@ -47,6 +47,9 @@ {new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")}, {new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")}, {new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")}, + {BigDecimal.valueOf(1, Integer.MIN_VALUE), + BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)), + BigDecimal.valueOf(1, -256)}, }; for(BigDecimal [] testCase: moreTestCases) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/IDN/IllegalArg.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8020842 + * @summary IDN do not throw IAE when hostname ends with a trailing dot + */ + +import java.net.*; + +public class IllegalArg { + + public static void main(String[] args) throws Exception { + String[] illegalNames = { + "com..net", + "com..", + ".com", + ".com." + }; + + String[] legalNames = { + "example.com", + "com\u3002", + "com.", + "." + }; + + for (String name : illegalNames) { + try { + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + + try { + IDN.toASCII(name); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + + for (String name : legalNames) { + System.out.println("Convering " + name); + System.out.println(IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/ServerSocket/SelectFdsLimit.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8021820 + * @summary The total number of file descriptors is limited to + * 1024(FDSET_SIZE) on MacOSX (the size of fd array passed to select() + * call in java.net classes is limited to this value). + * @run main/othervm SelectFdsLimit + * @author aleksej.efimov@oracle.com + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.SocketTimeoutException; + + +/* + * Test must be run in othervm mode to ensure that all files + * opened by openFiles() are closed propertly. +*/ +public class SelectFdsLimit { + static final int FDTOOPEN = 1023; + static final String TESTFILE = "testfile"; + static FileInputStream [] testFIS; + + static void prepareTestEnv() throws IOException { + File fileToCreate = new File(TESTFILE); + if (!fileToCreate.exists()) + if (!fileToCreate.createNewFile()) + throw new RuntimeException("Can't create test file"); + } + + //If there will be some problem (i.e. ulimits on number of opened files will fail) + //then this method will fail with exception and test will be considered as + //failed. But allocated fds will be released because the test is executed by + //dedicated VM (@run main/othervm). + static void openFiles(int fn, File f) throws FileNotFoundException, IOException { + testFIS = new FileInputStream[FDTOOPEN]; + for (;;) { + if (0 == fn) + break; + FileInputStream fis = new FileInputStream(f); + testFIS[--fn] = fis; + } + } + + public static void main(String [] args) throws IOException, FileNotFoundException { + + //The bug 8021820 is a Mac specific and because of that test will pass on all + //other platforms + if (!System.getProperty("os.name").contains("OS X")) { + return; + } + + //Create test directory with test files + prepareTestEnv(); + + //Consume FD ids for this java process to overflow the 1024 + openFiles(FDTOOPEN,new File(TESTFILE)); + + //Wait for incoming connection and make the select() used in java.net + //classes fail the limitation on FDSET_SIZE + ServerSocket socket = new ServerSocket(0); + + //Set the minimal timeout, no one is + //going to connect to this server socket + socket.setSoTimeout(1); + + // The accept() call will throw SocketException if the + // select() has failed due to limitation on fds size, + // indicating test failure. A SocketTimeoutException + // is expected, so it is caught and ignored, and the test + // passes. + try { + socket.accept(); + } catch (SocketTimeoutException e) { } + } +}
--- a/test/java/nio/file/WatchService/SensitivityModifier.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/nio/file/WatchService/SensitivityModifier.java Tue Aug 27 12:27:31 2013 -0400 @@ -54,60 +54,66 @@ @SuppressWarnings("unchecked") static void doTest(Path top) throws Exception { FileSystem fs = top.getFileSystem(); - WatchService watcher = fs.newWatchService(); + try (WatchService watcher = fs.newWatchService()) { - // create directories and files - int nDirs = 5 + rand.nextInt(20); - int nFiles = 50 + rand.nextInt(50); - Path[] dirs = new Path[nDirs]; - Path[] files = new Path[nFiles]; - for (int i=0; i<nDirs; i++) { - dirs[i] = Files.createDirectory(top.resolve("dir" + i)); - } - for (int i=0; i<nFiles; i++) { - Path dir = dirs[rand.nextInt(nDirs)]; - files[i] = Files.createFile(dir.resolve("file" + i)); - } + // create directories and files + int nDirs = 5 + rand.nextInt(20); + int nFiles = 50 + rand.nextInt(50); + Path[] dirs = new Path[nDirs]; + Path[] files = new Path[nFiles]; + for (int i=0; i<nDirs; i++) { + dirs[i] = Files.createDirectory(top.resolve("dir" + i)); + } + for (int i=0; i<nFiles; i++) { + Path dir = dirs[rand.nextInt(nDirs)]; + files[i] = Files.createFile(dir.resolve("file" + i)); + } - // register the directories (random sensitivity) - register(dirs, watcher); + // register the directories (random sensitivity) + register(dirs, watcher); - // sleep a bit here to ensure that modification to the first file - // can be detected by polling implementations (ie: last modified time - // may not change otherwise). - try { Thread.sleep(1000); } catch (InterruptedException e) { } + // sleep a bit here to ensure that modification to the first file + // can be detected by polling implementations (ie: last modified time + // may not change otherwise). + try { Thread.sleep(1000); } catch (InterruptedException e) { } - // modify files and check that events are received - for (int i=0; i<10; i++) { - Path file = files[rand.nextInt(nFiles)]; - System.out.println("Modify: " + file); - try (OutputStream out = Files.newOutputStream(file)) { - out.write(new byte[100]); + // modify files and check that events are received + for (int i=0; i<10; i++) { + Path file = files[rand.nextInt(nFiles)]; + System.out.println("Modify: " + file); + try (OutputStream out = Files.newOutputStream(file)) { + out.write(new byte[100]); + } + + System.out.println("Waiting for event(s)..."); + boolean eventReceived = false; + WatchKey key = watcher.take(); + do { + for (WatchEvent<?> event: key.pollEvents()) { + if (event.kind() != ENTRY_MODIFY) + throw new RuntimeException("Unexpected event: " + event); + Path name = ((WatchEvent<Path>)event).context(); + if (name.equals(file.getFileName())) { + eventReceived = true; + break; + } + } + key.reset(); + key = watcher.poll(1, TimeUnit.SECONDS); + } while (key != null && !eventReceived); + + // we should have received at least one ENTRY_MODIFY event + if (eventReceived) { + System.out.println("Event OK"); + } else { + throw new RuntimeException("No ENTRY_MODIFY event received for " + file); + } + + // re-register the directories to force changing their sensitivity + // level + register(dirs, watcher); } - System.out.println("Waiting for event..."); - WatchKey key = watcher.take(); - WatchEvent<?> event = key.pollEvents().iterator().next(); - if (event.kind() != ENTRY_MODIFY) - throw new RuntimeException("Unexpected event: " + event); - Path name = ((WatchEvent<Path>)event).context(); - if (!name.equals(file.getFileName())) - throw new RuntimeException("Unexpected context: " + name); - System.out.println("Event OK"); - - // drain events (to avoid interference) - do { - key.pollEvents(); - key.reset(); - key = watcher.poll(1, TimeUnit.SECONDS); - } while (key != null); - - // re-register the directories to force changing their sensitivity - // level - register(dirs, watcher); } - - // done - watcher.close(); } public static void main(String[] args) throws Exception {
--- a/test/java/time/tck/java/time/chrono/TCKChronology.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/time/tck/java/time/chrono/TCKChronology.java Tue Aug 27 12:27:31 2013 -0400 @@ -148,7 +148,7 @@ @DataProvider(name = "calendarDisplayName") Object[][] data_of_calendarDisplayNames() { return new Object[][] { - {"Hijrah", "Hijrah-umalqura"}, + {"Hijrah", "Islamic Umm al-Qura Calendar"}, {"ISO", "ISO"}, {"Japanese", "Japanese Calendar"}, {"Minguo", "Minguo Calendar"},
--- a/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Tue Aug 27 12:27:31 2013 -0400 @@ -438,13 +438,13 @@ // Test to verify the formatted dates @Test(dataProvider="patternMonthNames") public void test_ofPattern(int year, int month, int day, String expected) { - DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy"); + DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy", Locale.US); assertEquals(test.format(HijrahDate.of(year, month, day)), expected); } // Data provider for localized dates @DataProvider(name="chronoDateTimes") - Object[][] data_chronodatetimes() { + Object[][] data_chronodatetimes() { return new Object[][] { {1432, 12, 29, "Safar 1, 1434 AH"}, {1433, 1, 30, "Safar 30, 1434 AH"}, @@ -463,7 +463,7 @@ hdt = hdt.plus(1, ChronoUnit.HOURS); hdt = hdt.plus(1, ChronoUnit.MINUTES); hdt = hdt.plus(1, ChronoUnit.SECONDS); - DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.forLanguageTag("en-US")); + DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.US); assertEquals(df.format(hdt), expected); }
--- a/test/java/time/test/java/util/TestFormatter.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/time/test/java/util/TestFormatter.java Tue Aug 27 12:27:31 2013 -0400 @@ -22,16 +22,27 @@ */ package test.java.util; +import static org.testng.Assert.assertEquals; + import java.time.Instant; +import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZonedDateTime; import java.time.ZoneId; + +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; +import java.time.chrono.Chronology; + import java.time.temporal.ChronoField; +import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalAccessor; import java.util.*; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; /* @test * @summary Unit test for j.u.Formatter threeten date/time support @@ -57,18 +68,32 @@ private int total = 0; private int failure = 0; - private boolean verbose = true; + private boolean verbose = false; - @Test - public void test () { + @DataProvider(name = "calendarsByLocale") + Object[][] data_calendars() { + return new Object[][] { + {"en_US"}, + {"th_TH"}, + {"ja-JP-u-ca-japanese"}, + }; + } + @Test(dataProvider="calendarsByLocale") + public void test (String calendarLocale) { + failure = 0; int N = 12; //locales = Locale.getAvailableLocales(); Locale[] locales = new Locale[] { Locale.ENGLISH, Locale.FRENCH, Locale.JAPANESE, Locale.CHINESE}; Random r = new Random(); - ZonedDateTime zdt0 = ZonedDateTime.now(); - ZonedDateTime[] zdts = new ZonedDateTime[] { + + Locale calLocale = Locale.forLanguageTag(calendarLocale); + Chronology chrono = Chronology.ofLocale(calLocale); + ChronoLocalDate now = chrono.dateNow(); + ChronoLocalDateTime<?> ldt0 = now.atTime(LocalTime.now()); + ChronoZonedDateTime<?> zdt0 = ldt0.atZone(ZoneId.systemDefault()); + ChronoZonedDateTime<?>[] zdts = new ChronoZonedDateTime<?>[] { zdt0, zdt0.withZoneSameLocal(ZoneId.of("UTC")), zdt0.withZoneSameLocal(ZoneId.of("GMT")), @@ -76,11 +101,11 @@ }; while (N-- > 0) { - for (ZonedDateTime zdt : zdts) { - zdt = zdt.withDayOfYear(r.nextInt(365) + 1) + for (ChronoZonedDateTime<?> zdt : zdts) { + zdt = zdt.with(ChronoField.DAY_OF_YEAR, (r.nextInt(365) + 1)) .with(ChronoField.SECOND_OF_DAY, r.nextInt(86400)); Instant instant = zdt.toInstant(); - Calendar cal = Calendar.getInstance(); + Calendar cal = Calendar.getInstance(calLocale); cal.setTimeInMillis(instant.toEpochMilli()); cal.setTimeZone(TimeZone.getTimeZone(zdt.getZone())); for (Locale locale : locales) { @@ -106,8 +131,19 @@ } private String getClassName(Object o) { - Class c = o.getClass(); - return c.getName().substring(c.getPackage().getName().length() + 1); + Class<?> c = o.getClass(); + String clname = c.getName().substring(c.getPackage().getName().length() + 1); + if (o instanceof TemporalAccessor) { + Chronology chrono = ((TemporalAccessor)o).query(TemporalQuery.chronology()); + if (chrono != null) { + clname = clname + "(" + chrono.getId() + ")"; + } + } + if (o instanceof Calendar) { + String type = ((Calendar)o).getCalendarType(); + clname = clname + "(" + type + ")"; + } + return clname; } private String test(String fmtStr, Locale locale, @@ -115,12 +151,12 @@ String out = new Formatter( new StringBuilder(), locale).format(fmtStr, dt).out().toString(); if (verbose) { - System.out.printf("%-18s : %s%n", getClassName(dt), out); + System.out.printf("%-24s : %s%n", getClassName(dt), out); } if (expected != null && !out.equals(expected)) { - System.out.printf("=====>%-18s : %s [ FAILED expected: %s ]%n", + System.out.printf("%-24s actual: %s%n FAILED; expected: %s%n", getClassName(dt), out, expected); - new RuntimeException().printStackTrace(); + new RuntimeException().printStackTrace(System.out); failure++; } total++; @@ -135,24 +171,29 @@ } private void testDate(String fmtStr, Locale locale, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime<?> zdt, Calendar cal) { printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); test(fmtStr, locale, expected, zdt.toLocalDateTime()); test(fmtStr, locale, expected, zdt.toLocalDate()); + if (zdt instanceof ZonedDateTime) { + test(fmtStr, locale, expected, ((ZonedDateTime)zdt).toOffsetDateTime()); + } } private void testTime(String fmtStr, Locale locale, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime<?> zdt, Calendar cal) { printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); test(fmtStr, locale, expected, zdt.toLocalDateTime()); - test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime()); test(fmtStr, locale, expected, zdt.toLocalTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + test(fmtStr, locale, expected, odt.toOffsetTime()); + } } private String toZoneIdStr(String expected) { @@ -164,7 +205,7 @@ .replaceAll("GMT|UTC|UT", "Z"); } - private void testZoneId(Locale locale, ZonedDateTime zdt, Calendar cal) { + private void testZoneId(Locale locale, ChronoZonedDateTime<?> zdt, Calendar cal) { String fmtStr = "z:[%tz] z:[%1$Tz] Z:[%1$tZ] Z:[%1$TZ]"; printFmtStr(locale, fmtStr); String expected = toZoneIdStr(test(fmtStr, locale, null, cal)); @@ -174,8 +215,11 @@ cal0.setTimeInMillis(zdt.toInstant().toEpochMilli()); cal0.setTimeZone(TimeZone.getTimeZone("GMT" + zdt.getOffset().getId())); expected = toZoneOffsetStr(test(fmtStr, locale, null, cal0)); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); - test(fmtStr, locale, expected, zdt.toOffsetDateTime().toOffsetTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + test(fmtStr, locale, expected, odt.toOffsetTime()); + } // datetime + zid fmtStr = "c:[%tc] c:[%1$Tc]"; @@ -185,12 +229,15 @@ } private void testInstant(Locale locale, Instant instant, - ZonedDateTime zdt, Calendar cal) { + ChronoZonedDateTime<?> zdt, Calendar cal) { String fmtStr = "s:[%ts] s:[%1$Ts] Q:[%1$tQ] Q:[%1$TQ]"; printFmtStr(locale, fmtStr); String expected = test(fmtStr, locale, null, cal); test(fmtStr, locale, expected, instant); test(fmtStr, locale, expected, zdt); - test(fmtStr, locale, expected, zdt.toOffsetDateTime()); + if (zdt instanceof ZonedDateTime) { + OffsetDateTime odt = ((ZonedDateTime)zdt).toOffsetDateTime(); + test(fmtStr, locale, expected, odt); + } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/Arrays/TimSortStackSize.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8011944 + * @summary Test TimSort stack size + */ +import java.util.Arrays; +import java.util.ArrayDeque; + +public class TimSortStackSize { + + public static void main(String[] args) { + testComparableTimSort(); + testTimSort(); + } + + static void testComparableTimSort() { + System.out.printf("testComparableTimSort()%n"); + Arrays.sort(genData()); + } + + static void testTimSort() { + System.out.printf("testTimSort()%n"); + Arrays.sort(genData(), Integer::compare); + } + + private static final int MIN = 16; + + private static final int BOUND1 = 2 * MIN + 1; + private static final int BOUND2 = BOUND1 + MIN + 2; + private static final int BOUND3 = BOUND1 + 1 + BOUND2; + private static final int BOUND4 = BOUND2 + 1 + BOUND3; + private static final int BOUND5 = BOUND3 + 1 + BOUND4; + + static int build(int size, int B, ArrayDeque<Integer> chunks) { + chunks.addFirst(B); + if (size < BOUND1) { + chunks.addFirst(size); + return size; + } + + int asize = (size + 2) / 2; + if (size >= BOUND2 && asize < BOUND1) { + asize = BOUND1; + } else if (size >= BOUND3 && asize < BOUND2) { + asize = BOUND2; + } else if (size >= BOUND4 && asize < BOUND3) { + asize = BOUND3; + } else if (size >= BOUND5 && asize < BOUND4) { + asize = BOUND4; + } + if (size - asize >= B) { + throw new AssertionError(" " + size + " , " + asize + " , " + B); + } + return build(asize, size - asize, chunks); + } + + static Integer[] genData() { + ArrayDeque<Integer> chunks = new ArrayDeque<Integer>(); + chunks.addFirst(MIN); + + int B = MIN + 4; + int A = B + MIN + 1; + + for (int i = 0; i < 8; i++) { + int eps = build(A, B, chunks); + B = B + A + 1; + A = B + eps + 1; + } + chunks.addFirst(B); + chunks.addFirst(A); + int total = 0; + for (Integer len : chunks) { + total += len; + } + int pow = MIN; + while (pow < total) { + pow += pow; + } + chunks.addLast(pow - total); + System.out.println(" Total: " + total); + Integer[] array = new Integer[pow]; + int off = 0; + int pos = 0; + for (Integer len : chunks) { + for (int i = 0; i < len; i++) { + array[pos++] = Integer.valueOf(i == 0 ? 0 : 1); + } + off++; + } + return array; + } + +}
--- a/test/java/util/Collection/ListDefaults.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/util/Collection/ListDefaults.java Tue Aug 27 12:27:31 2013 -0400 @@ -49,6 +49,7 @@ /** * @test + * @bug 8023367 * @library testlibrary * @build CollectionAsserts CollectionSupplier * @run testng ListDefaults @@ -100,6 +101,7 @@ @DataProvider(name="listProvider", parallel=true) public static Object[][] listCases() { final List<Object[]> cases = new LinkedList<>(); + cases.add(new Object[] { Collections.emptyList() }); cases.add(new Object[] { new ArrayList<>() }); cases.add(new Object[] { new LinkedList<>() }); cases.add(new Object[] { new Vector<>() }); @@ -128,6 +130,11 @@ list.removeIf(null); fail("expected NPE not thrown"); } catch (NullPointerException npe) {} + try { + list.sort(null); + } catch (Throwable t) { + fail("Exception not expected: " + t); + } } @Test
--- a/test/java/util/Comparator/TypeTest.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/java/util/Comparator/TypeTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -75,7 +75,7 @@ } } - public static void main(String[] args) { + public void testOrder() { Manager m1 = new Manager("Manager", 2, 2000); Manager m2 = new Manager("Manager", 4, 1300);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/SplittableRandom/SplittableRandomTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,511 @@ +/* + * 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. + */ + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.SplittableRandom; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.LongAdder; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +/** + * @test + * @run testng SplittableRandomTest + * @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest + * @summary test methods on SplittableRandom + */ +@Test +public class SplittableRandomTest { + + // Note: this test was copied from the 166 TCK SplittableRandomTest test + // and modified to be a TestNG test + + /* + * Testing coverage notes: + * + * 1. Many of the test methods are adapted from ThreadLocalRandomTest. + * + * 2. These tests do not check for random number generator quality. + * But we check for minimal API compliance by requiring that + * repeated calls to nextX methods, up to NCALLS tries, produce at + * least two distinct results. (In some possible universe, a + * "correct" implementation might fail, but the odds are vastly + * less than that of encountering a hardware failure while running + * the test.) For bounded nextX methods, we sample various + * intervals across multiples of primes. In other tests, we repeat + * under REPS different values. + */ + + // max numbers of calls to detect getting stuck on one value + static final int NCALLS = 10000; + + // max sampled int bound + static final int MAX_INT_BOUND = (1 << 28); + + // max sampled long bound + static final long MAX_LONG_BOUND = (1L << 42); + + // Number of replications for other checks + static final int REPS = 20; + + /** + * Repeated calls to nextInt produce at least two distinct results + */ + public void testNextInt() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(); + int i = 0; + while (i < NCALLS && sr.nextInt() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Repeated calls to nextLong produce at least two distinct results + */ + public void testNextLong() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(); + int i = 0; + while (i < NCALLS && sr.nextLong() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Repeated calls to nextDouble produce at least two distinct results + */ + public void testNextDouble() { + SplittableRandom sr = new SplittableRandom(); + double f = sr.nextDouble(); + int i = 0; + while (i < NCALLS && sr.nextDouble() == f) + ++i; + assertTrue(i < NCALLS); + } + + /** + * Two SplittableRandoms created with the same seed produce the + * same values for nextLong. + */ + public void testSeedConstructor() { + for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) { + SplittableRandom sr1 = new SplittableRandom(seed); + SplittableRandom sr2 = new SplittableRandom(seed); + for (int i = 0; i < REPS; ++i) + assertEquals(sr1.nextLong(), sr2.nextLong()); + } + } + + /** + * A SplittableRandom produced by split() of a default-constructed + * SplittableRandom generates a different sequence + */ + public void testSplit1() { + SplittableRandom sr = new SplittableRandom(); + for (int reps = 0; reps < REPS; ++reps) { + SplittableRandom sc = sr.split(); + int i = 0; + while (i < NCALLS && sr.nextLong() == sc.nextLong()) + ++i; + assertTrue(i < NCALLS); + } + } + + /** + * A SplittableRandom produced by split() of a seeded-constructed + * SplittableRandom generates a different sequence + */ + public void testSplit2() { + SplittableRandom sr = new SplittableRandom(12345); + for (int reps = 0; reps < REPS; ++reps) { + SplittableRandom sc = sr.split(); + int i = 0; + while (i < NCALLS && sr.nextLong() == sc.nextLong()) + ++i; + assertTrue(i < NCALLS); + } + } + + /** + * nextInt(negative) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextIntBoundedNeg() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(-17); + } + + /** + * nextInt(least >= bound) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextIntBadBounds() { + SplittableRandom sr = new SplittableRandom(); + int f = sr.nextInt(17, 2); + } + + /** + * nextInt(bound) returns 0 <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextIntBounded() { + SplittableRandom sr = new SplittableRandom(); + // sample bound space across prime number increments + for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) { + int f = sr.nextInt(bound); + assertTrue(0 <= f && f < bound); + int i = 0; + int j; + while (i < NCALLS && + (j = sr.nextInt(bound)) == f) { + assertTrue(0 <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + + /** + * nextInt(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextIntBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) { + for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) { + int f = sr.nextInt(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + int j; + while (i < NCALLS && + (j = sr.nextInt(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * nextLong(negative) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextLongBoundedNeg() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(-17); + } + + /** + * nextLong(least >= bound) throws IllegalArgumentException + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testNextLongBadBounds() { + SplittableRandom sr = new SplittableRandom(); + long f = sr.nextLong(17, 2); + } + + /** + * nextLong(bound) returns 0 <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextLongBounded() { + SplittableRandom sr = new SplittableRandom(); + for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) { + long f = sr.nextLong(bound); + assertTrue(0 <= f && f < bound); + int i = 0; + long j; + while (i < NCALLS && + (j = sr.nextLong(bound)) == f) { + assertTrue(0 <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + + /** + * nextLong(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextLongBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) { + for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) { + long f = sr.nextLong(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + long j; + while (i < NCALLS && + (j = sr.nextLong(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * nextDouble(least, bound) returns least <= value < bound; + * repeated calls produce at least two distinct results + */ + public void testNextDoubleBounded2() { + SplittableRandom sr = new SplittableRandom(); + for (double least = 0.0001; least < 1.0e20; least *= 8) { + for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) { + double f = sr.nextDouble(least, bound); + assertTrue(least <= f && f < bound); + int i = 0; + double j; + while (i < NCALLS && + (j = sr.nextDouble(least, bound)) == f) { + assertTrue(least <= j && j < bound); + ++i; + } + assertTrue(i < NCALLS); + } + } + } + + /** + * Invoking sized ints, long, doubles, with negative sizes throws + * IllegalArgumentException + */ + public void testBadStreamSize() { + SplittableRandom r = new SplittableRandom(); + executeAndCatchIAE(() -> r.ints(-1L)); + executeAndCatchIAE(() -> r.ints(-1L, 2, 3)); + executeAndCatchIAE(() -> r.longs(-1L)); + executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L)); + executeAndCatchIAE(() -> r.doubles(-1L)); + executeAndCatchIAE(() -> r.doubles(-1L, .5, .6)); + } + + /** + * Invoking bounded ints, long, doubles, with illegal bounds throws + * IllegalArgumentException + */ + public void testBadStreamBounds() { + SplittableRandom r = new SplittableRandom(); + executeAndCatchIAE(() -> r.ints(2, 1)); + executeAndCatchIAE(() -> r.ints(10, 42, 42)); + executeAndCatchIAE(() -> r.longs(-1L, -1L)); + executeAndCatchIAE(() -> r.longs(10, 1L, -2L)); + executeAndCatchIAE(() -> r.doubles(0.0, 0.0)); + executeAndCatchIAE(() -> r.doubles(10, .5, .4)); + } + + private void executeAndCatchIAE(Runnable r) { + executeAndCatch(IllegalArgumentException.class, r); + } + + private void executeAndCatch(Class<? extends Exception> expected, Runnable r) { + Exception caught = null; + try { + r.run(); + } + catch (Exception e) { + caught = e; + } + + assertNotNull(caught, + String.format("No Exception was thrown, expected an Exception of %s to be thrown", + expected.getName())); + Assert.assertTrue(expected.isInstance(caught), + String.format("Exception thrown %s not an instance of %s", + caught.getClass().getName(), expected.getName())); + } + + /** + * A parallel sized stream of ints generates the given number of values + */ + public void testIntsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.ints(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * A parallel sized stream of longs generates the given number of values + */ + public void testLongsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.longs(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * A parallel sized stream of doubles generates the given number of values + */ + public void testDoublesCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 0; + for (int reps = 0; reps < REPS; ++reps) { + counter.reset(); + r.doubles(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + size += 524959; + } + } + + /** + * Each of a parallel sized stream of bounded ints is within bounds + */ + public void testBoundedInts() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 12345L; + for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) { + for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) { + final int lo = least, hi = bound; + r.ints(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * Each of a parallel sized stream of bounded longs is within bounds + */ + public void testBoundedLongs() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 123L; + for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) { + for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) { + final long lo = least, hi = bound; + r.longs(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * Each of a parallel sized stream of bounded doubles is within bounds + */ + public void testBoundedDoubles() { + AtomicInteger fails = new AtomicInteger(0); + SplittableRandom r = new SplittableRandom(); + long size = 456; + for (double least = 0.00011; least < 1.0e20; least *= 9) { + for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) { + final double lo = least, hi = bound; + r.doubles(size, lo, hi).parallel(). + forEach(x -> {if (x < lo || x >= hi) + fails.getAndIncrement(); }); + } + } + assertEquals(fails.get(), 0); + } + + /** + * A parallel unsized stream of ints generates at least 100 values + */ + public void testUnsizedIntsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.ints().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A parallel unsized stream of longs generates at least 100 values + */ + public void testUnsizedLongsCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.longs().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A parallel unsized stream of doubles generates at least 100 values + */ + public void testUnsizedDoublesCount() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.doubles().limit(size).parallel().forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of ints generates at least 100 values + */ + public void testUnsizedIntsCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.ints().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of longs generates at least 100 values + */ + public void testUnsizedLongsCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.longs().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + + /** + * A sequential unsized stream of doubles generates at least 100 values + */ + public void testUnsizedDoublesCountSeq() { + LongAdder counter = new LongAdder(); + SplittableRandom r = new SplittableRandom(); + long size = 100; + r.doubles().limit(size).forEach(x -> {counter.increment();}); + assertEquals(counter.sum(), size); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,88 @@ +/* + * 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/othervm/timeout=60 ReadersUnlockAfterWriteUnlock + * @bug 8023234 + * @summary StampedLock serializes readers on writer unlock + * @author Dmitry Chyuko + * @author Aleksey Shipilev + */ + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.locks.StampedLock; + +public class ReadersUnlockAfterWriteUnlock { + static final int RNUM = 2; + static final StampedLock sl = new StampedLock(); + static volatile boolean isDone; + + static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1); + static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM); + static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1); + + static class Reader extends Thread { + final String name; + Reader(String name) { + super(); + this.name = name; + } + public void run() { + while (!isDone && !isInterrupted()) { + try { + iterationStart.await(); + writerHasLock.await(); + long rs = sl.readLock(); + + // single reader blocks here indefinitely if readers + // are serialized + readersHaveLocks.await(); + + sl.unlockRead(rs); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + } + } + + public static void main(String[] args) throws InterruptedException { + for (int r = 0 ; r < RNUM; ++r) { + new Reader("r" + r).start(); + } + int i; + for (i = 0; i < 1024; ++i) { + try { + iterationStart.await(); + long ws = sl.writeLock(); + writerHasLock.await(); + Thread.sleep(10); + sl.unlockWrite(ws); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + isDone = true; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/Logger/getLogger/TestLogger.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +/** + * @test + * @bug 8005899 + * @build TestLogger testlogger.MyResource + * @run main/othervm TestLogger + * @run main/othervm -Dsecurity=on TestLogger + **/ +public class TestLogger { + + public static final String RESOURCE_BUNDLE = "testlogger.MyResource"; + public static final String ORG_LOGGER = "org"; + public static final String FOO_LOGGER = ORG_LOGGER + ".foo.Foo"; + public static final String BAR_LOGGER = ORG_LOGGER + ".bar.Bar"; + public static final String GEE_LOGGER = ORG_LOGGER + ".gee.Gee"; + public static final String GEE_GEE_LOGGER = GEE_LOGGER+".Gee"; + + public static void main(String[] args) { + final String security = System.getProperty("security", "off"); + System.out.println("Security is " + security); + if ("on".equals(security)) { + System.setSecurityManager(new SecurityManager()); + } + + newLogger(FOO_LOGGER, RESOURCE_BUNDLE); + newLogger(FOO_LOGGER); + newLogger(BAR_LOGGER); + newLogger(BAR_LOGGER, RESOURCE_BUNDLE); + newLogger(GEE_LOGGER, null); + newLogger(GEE_LOGGER, RESOURCE_BUNDLE); + newLogger(ORG_LOGGER); + newLogger(GEE_GEE_LOGGER); + + for (String log : new String[] { FOO_LOGGER, BAR_LOGGER, GEE_LOGGER }) { + if (!RESOURCE_BUNDLE.equals(Logger.getLogger(log).getResourceBundleName())) { + throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log); + } + try { + Logger logger = Logger.getLogger(log, null); + if (!RESOURCE_BUNDLE.equals(logger.getResourceBundleName())) { + throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log); + } + throw new RuntimeException("Expected IllegalArgumentException not thrown for " + log); + } catch (IllegalArgumentException e) { + System.out.println("Got expected exception for " + log +": " + e); + } + } + for (String log : new String[] { ORG_LOGGER, GEE_GEE_LOGGER }) { + if (Logger.getLogger(log).getResourceBundleName() != null) { + throw new RuntimeException("Resource bundle is not null for log: " + + Logger.getLogger(log).getResourceBundleName()); + } + try { + Logger logger = Logger.getLogger(log, null); + if (logger.getResourceBundleName() != null) { + throw new RuntimeException("Resource bundle is not null for log: " + + logger.getResourceBundleName()); + } + System.out.println("Success calling Logger.getLogger(\""+log+"\", null)"); + } catch (IllegalArgumentException e) { + throw new RuntimeException("Unexpected exception for " + log +": " + e, e); + } + } + } + + private static List<Logger> strongRefs = new ArrayList<>(); + private static void newLogger(String name) { + strongRefs.add(Logger.getLogger(name)); + } + private static void newLogger(String name, String resourceBundleName) { + strongRefs.add(Logger.getLogger(name, resourceBundleName)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package testlogger; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; +import java.util.ResourceBundle; + +/** + * A dummy resource bundle for testing purposes. + * @author danielfuchs + */ +public class MyResource extends ResourceBundle { + Map<String, Object> bundle = new HashMap<>(); + + @Override + protected Object handleGetObject(String key) { + bundle.put(key,"Localized: " + key); + return bundle.get(key); + } + + @Override + public Enumeration<String> getKeys() { + final Hashtable<String, Object> h = new Hashtable<>(bundle); + return h.keys(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/regex/PatternTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @summary Unit tests for wrapping classes should delegate to default methods + * @library ../stream/bootlib + * @build java.util.stream.OpTestCase + * @run testng/othervm PatternTest + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +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; + +@Test +public class PatternTest extends OpTestCase { + + @DataProvider(name = "Stream<String>") + public static Object[][] makeStreamTestData() { + List<Object[]> data = new ArrayList<>(); + + String description = ""; + String input = "awgqwefg1fefw4vssv1vvv1"; + Pattern pattern = Pattern.compile("4"); + List<String> expected = new ArrayList<>(); + expected.add("awgqwefg1fefw"); + expected.add("vssv1vvv1"); + + // Must match the type signature of the consumer of this data, testStrings + // String, String, Pattern, List<String> + data.add(new Object[]{description, input, pattern, expected}); + + 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}); + + + 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}); + + + 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}); + + + 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}); + + + 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}); + + + input = ""; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + + data.add(new Object[]{description, input, pattern, expected}); + + + 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, expected}); + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "Stream<String>") + public void testStrings(String description, String input, Pattern pattern, List<String> expected) { + Supplier<Stream<String>> ss = () -> pattern.splitAsStream(input); + withData(TestData.Factory.ofSupplier(description, ss)) + .stream(LambdaTestHelpers.identity()) + .expectedResult(expected) + .exercise(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.tests.java.util; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Spliterator; +import java.util.SplittableRandom; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.DoubleStream; +import java.util.stream.DoubleStreamTestScenario; +import java.util.stream.IntStream; +import java.util.stream.IntStreamTestScenario; +import java.util.stream.LongStream; +import java.util.stream.LongStreamTestScenario; +import java.util.stream.OpTestCase; +import java.util.stream.StreamSupport; +import java.util.stream.TestData; + +@Test +public class SplittableRandomTest extends OpTestCase { + + static class RandomBoxedSpliterator<T> implements Spliterator<T> { + final SplittableRandom rng; + long index; + final long fence; + final Function<SplittableRandom, T> rngF; + + RandomBoxedSpliterator(SplittableRandom rng, long index, long fence, Function<SplittableRandom, T> rngF) { + this.rng = rng; + this.index = index; + this.fence = fence; + this.rngF = rngF; + } + + public RandomBoxedSpliterator<T> trySplit() { + long i = index, m = (i + fence) >>> 1; + return (m <= i) ? null : + new RandomBoxedSpliterator<>(rng.split(), i, index = m, rngF); + } + + public long estimateSize() { + return fence - index; + } + + public int characteristics() { + return (Spliterator.SIZED | Spliterator.SUBSIZED | + Spliterator.NONNULL | Spliterator.IMMUTABLE); + } + + @Override + public boolean tryAdvance(Consumer<? super T> consumer) { + if (consumer == null) throw new NullPointerException(); + long i = index, f = fence; + if (i < f) { + consumer.accept(rngF.apply(rng)); + index = i + 1; + return true; + } + return false; + } + } + + static final int SIZE = 1 << 16; + + // Ensure there is a range of a power of 2 + static final int[] BOUNDS = {256}; + static final int[] ORIGINS = {-16, 0, 16}; + + static <T extends Comparable<T>> ResultAsserter<Iterable<T>> randomAsserter(int size, T origin, T bound) { + return (act, exp, ord, par) -> { + int count = 0; + Set<Comparable<T>> values = new HashSet<>(); + for (Comparable<T> t : act) { + if (origin.compareTo(bound) < 0) { + assertTrue(t.compareTo(origin) >= 0); + assertTrue(t.compareTo(bound) < 0); + } + values.add(t); + count++; + } + assertEquals(count, size); + // Assert that at least one different result is produced + // For the size of the data it is highly improbable that this + // will cause a false negative (i.e. a false failure) + assertTrue(values.size() > 1); + }; + } + + @DataProvider(name = "ints") + public static Object[][] intsDataProvider() { + List<Object[]> data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function<Function<SplittableRandom, Integer>, IntStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToInt(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints().limit(%d)", SIZE), + () -> new SplittableRandom().ints().limit(SIZE)), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d)", SIZE), + () -> new SplittableRandom().ints(SIZE)), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())", SIZE), + () -> rbsf.apply(sr -> sr.nextInt())), + randomAsserter(SIZE, Integer.MAX_VALUE, 0) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final int origin = o; + final int bound = b; + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d, %d).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().ints(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new SplittableRandom().ints(%d, %d, %d)", SIZE, origin, bound), + () -> new SplittableRandom().ints(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextInt(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofIntSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextInt(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "ints") + public void testInts(TestData.OfInt data, ResultAsserter<Iterable<Integer>> ra) { + withData(data). + stream(s -> s). + without(IntStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } + + @DataProvider(name = "longs") + public static Object[][] longsDataProvider() { + List<Object[]> data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function<Function<SplittableRandom, Long>, LongStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToLong(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs().limit(%d)", SIZE), + () -> new SplittableRandom().longs().limit(SIZE)), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d)", SIZE), + () -> new SplittableRandom().longs(SIZE)), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())", SIZE), + () -> rbsf.apply(sr -> sr.nextLong())), + randomAsserter(SIZE, Long.MAX_VALUE, 0L) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final long origin = o; + final long bound = b; + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d, %d).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().longs(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new SplittableRandom().longs(%d, %d, %d)", SIZE, origin, bound), + () -> new SplittableRandom().longs(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextLong(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofLongSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextLong(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "longs") + public void testLongs(TestData.OfLong data, ResultAsserter<Iterable<Long>> ra) { + withData(data). + stream(s -> s). + without(LongStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } + + @DataProvider(name = "doubles") + public static Object[][] doublesDataProvider() { + List<Object[]> data = new ArrayList<>(); + + // Function to create a stream using a RandomBoxedSpliterator + + Function<Function<SplittableRandom, Double>, DoubleStream> rbsf = + sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false). + mapToDouble(i -> i); + + // Unbounded + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles().limit(%d)", SIZE), + () -> new SplittableRandom().doubles().limit(SIZE)), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%d)", SIZE), + () -> new SplittableRandom().doubles(SIZE)), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())", SIZE), + () -> rbsf.apply(sr -> sr.nextDouble())), + randomAsserter(SIZE, Double.MAX_VALUE, 0d) + }); + + // Bounded + + for (int b : BOUNDS) { + for (int o : ORIGINS) { + final double origin = o; + final double bound = b; + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%f, %f).limit(%d)", origin, bound, SIZE), + () -> new SplittableRandom().doubles(origin, bound).limit(SIZE)), + randomAsserter(SIZE, origin, bound) + }); + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new SplittableRandom().doubles(%d, %f, %f)", SIZE, origin, bound), + () -> new SplittableRandom().doubles(SIZE, origin, bound)), + randomAsserter(SIZE, origin, bound) + }); + + if (origin == 0) { + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))", SIZE, bound), + () -> rbsf.apply(sr -> sr.nextDouble(bound))), + randomAsserter(SIZE, origin, bound) + }); + } + + data.add(new Object[]{ + TestData.Factory.ofDoubleSupplier( + String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))", SIZE, origin, bound), + () -> rbsf.apply(sr -> sr.nextDouble(origin, bound))), + randomAsserter(SIZE, origin, bound) + }); + } + } + + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "doubles") + public void testDoubles(TestData.OfDouble data, ResultAsserter<Iterable<Double>> ra) { + withData(data). + stream(s -> s). + without(DoubleStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED). + resultAsserter(ra). + exercise(); + } +}
--- a/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -35,11 +35,12 @@ import javax.swing.*; public class ActionListenerCalledTwiceTest { - static String menuItems[] = { "Item1", "Item2", "Item3" }; + static String menuItems[] = { "Item1", "Item2", "Item3", "Item4" }; static KeyStroke keyStrokes[] = { KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK), + KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK) }; static volatile int listenerCallCounter = 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/awt/datatransfer/DataFlavorComparatorTest.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 7173464 + @summary Clipboard.getAvailableDataFlavors: Comparison method violates contract + @author Petr Pchelko + @run main DataFlavorComparatorTest +*/ + +import sun.awt.datatransfer.DataTransferer; + +import java.awt.datatransfer.DataFlavor; + +public class DataFlavorComparatorTest { + + public static void main(String[] args) { + DataTransferer.DataFlavorComparator comparator = new DataTransferer.DataFlavorComparator(); + DataFlavor flavor1 = DataFlavor.imageFlavor; + DataFlavor flavor2 = DataFlavor.selectionHtmlFlavor; + if (comparator.compare(flavor1, flavor2) == 0) { + throw new RuntimeException(flavor1.getMimeType() + " and " + flavor2.getMimeType() + + " should not be equal"); + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/auto/KPEquals.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8015669 + * @summary KerberosPrincipal::equals should ignore name-type + * @compile -XDignore.symbol.file KPEquals.java + * @run main/othervm KPEquals + */ + +import sun.security.jgss.GSSUtil; + +import javax.security.auth.kerberos.KerberosKey; +import javax.security.auth.kerberos.KerberosPrincipal; +import javax.security.auth.kerberos.KeyTab; + +public class KPEquals { + + public static void main(String[] args) throws Exception { + new OneKDC(null).writeJAASConf(); + Context c = Context.fromJAAS("client"); + Context s = Context.fromThinAir(); + KerberosPrincipal kp = new KerberosPrincipal( + OneKDC.SERVER + "@" + OneKDC.REALM, + KerberosPrincipal.KRB_NT_SRV_INST); + s.s().getPrincipals().add(kp); + for (KerberosKey k: KeyTab.getInstance(kp).getKeys(kp)) { + s.s().getPrivateCredentials().add(k); + } + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID); + Context.handshake(c, s); + } +}
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -21,14 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionCacheSizeTests - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; @@ -113,7 +115,9 @@ /* * Signal Client, we're ready for his connect. */ - serverReady = true; + if (createdPorts == serverPorts.length) { + serverReady = true; + } int read = 0; int nConnections = 0; /* @@ -310,7 +314,6 @@ * Fork off the other side, then do your work. */ SessionCacheSizeTests() throws Exception { - /* * create the SSLServerSocket and SSLSocket factories */ @@ -323,46 +326,87 @@ int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length); int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length); - if (separateServerThread) { - for (int i = 0; i < serverPorts.length; i++) { - - // distribute remaining connections among the available ports - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), true); - else - startServer(serverPorts[i], serverConns, true); + Exception startException = null; + try { + if (separateServerThread) { + for (int i = 0; i < serverPorts.length; i++) { + // distribute remaining connections among the + // available ports + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), true); + else + startServer(serverPorts[i], serverConns, true); + } + startClient(false); + } else { + startClient(true); + for (int i = 0; i < serverPorts.length; i++) { + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), false); + else + startServer(serverPorts[i], serverConns, false); + } } - startClient(false); - } else { - startClient(true); - for (int i = 0; i < serverPorts.length; i++) { - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), false); - else - startServer(serverPorts[i], serverConns, false); - } + } catch (Exception e) { + startException = e; } /* * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (serverThread != null) { + serverThread.join(); + } } else { - clientThread.join(); + if (clientThread != null) { + clientThread.join(); + } } /* * When we get here, the test is pretty much over. - * - * If the main thread excepted, that propagates back - * immediately. If the other thread threw an exception, we - * should report back. + */ + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. */ - if (serverException != null) - throw serverException; - if (clientException != null) - throw clientException; + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! } void startServer(final int port, final int nConns, @@ -387,7 +431,13 @@ }; serverThread.start(); } else { - doServerSide(port, nConns); + try { + doServerSide(port, nConns); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } } } @@ -409,7 +459,11 @@ }; clientThread.start(); } else { - doClientSide(); + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } } } }
--- a/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java Tue Aug 27 12:27:31 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -21,14 +21,14 @@ * questions. */ +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + /* * @test * @bug 4366807 * @summary Need new APIs to get/set session timeout and session cache size. * @run main/othervm SessionTimeOutTests - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; @@ -263,7 +263,7 @@ for (int i = 0; i < nConnections; i++) { sslSockets[i].close(); } - System.out.println("----------------------------------------" + System.out.println("----------------------------------------" + "-----------------------"); System.out.println("Session timeout test passed"); } @@ -348,45 +348,88 @@ int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length); int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length); - if (separateServerThread) { - for (int i = 0; i < serverPorts.length; i++) { - // distribute remaining connections among the available ports - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), true); - else - startServer(serverPorts[i], serverConns, true); + Exception startException = null; + try { + if (separateServerThread) { + for (int i = 0; i < serverPorts.length; i++) { + // distribute remaining connections among the + // vailable ports + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), true); + else + startServer(serverPorts[i], serverConns, true); + } + startClient(false); + } else { + startClient(true); + for (int i = 0; i < serverPorts.length; i++) { + if (i < remainingConns) + startServer(serverPorts[i], (serverConns + 1), false); + else + startServer(serverPorts[i], serverConns, false); + } } - startClient(false); - } else { - startClient(true); - for (int i = 0; i < serverPorts.length; i++) { - if (i < remainingConns) - startServer(serverPorts[i], (serverConns + 1), false); - else - startServer(serverPorts[i], serverConns, false); - } + } catch (Exception e) { + startException = e; } /* * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (serverThread != null) { + serverThread.join(); + } } else { - clientThread.join(); + if (clientThread != null) { + clientThread.join(); + } } /* * When we get here, the test is pretty much over. - * - * If the main thread excepted, that propagates back - * immediately. If the other thread threw an exception, we - * should report back. + * Which side threw the error? + */ + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. */ - if (serverException != null) - throw serverException; - if (clientException != null) - throw clientException; + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! } void startServer(final int port, final int nConns, @@ -411,7 +454,13 @@ }; serverThread.start(); } else { - doServerSide(port, nConns); + try { + doServerSide(port, nConns); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = 0; + } } } @@ -433,7 +482,11 @@ }; clientThread.start(); } else { - doClientSide(); + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8020842 + * @summary SNIHostName does not throw IAE when hostname ends + * with a trailing dot + */ + +import javax.net.ssl.SNIHostName; + +public class IllegalSNIName { + + public static void main(String[] args) throws Exception { + String[] illegalNames = { + "example\u3003\u3002com", + "example..com", + "com\u3002", + "com.", + "." + }; + + for (String name : illegalNames) { + try { + SNIHostName hostname = new SNIHostName(name); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + } +}
--- a/test/sun/security/ssl/templates/SSLSocketTemplate.java Tue Aug 27 12:04:32 2013 -0400 +++ b/test/sun/security/ssl/templates/SSLSocketTemplate.java Tue Aug 27 12:27:31 2013 -0400 @@ -243,7 +243,7 @@ * output it. */ if (exception != null) { - if (exception != startException) { + if (exception != startException && startException != null) { exception.addSuppressed(startException); } throw exception;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/tools/jarsigner/jvindex.sh Tue Aug 27 12:27:31 2013 -0400 @@ -0,0 +1,76 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8022761 +# @summary regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Windows_* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +F=abcde +KS=jvindex.jks +JFILE=jvindex.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ + -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit" + +rm $F $KS $JFILE 2> /dev/null + +echo 12345 > $F +$JAR cvf $JFILE $F + +ERR="" + +$KT -alias a -dname CN=a -genkey -validity 300 || ERR="$ERR 1" + +$JARSIGNER $JFILE a || ERR="$ERR 2" +$JAR i $JFILE + +# Make sure the $F line has "sm" (signed and in manifest) +$JARSIGNER -verify -verbose $JFILE | grep $F | grep sm || ERR="$ERR 3" + +if [ "$ERR" = "" ]; then + exit 0 +else + echo "ERR is $ERR" + exit 1 +fi + +