This commit is contained in:
Lana Steuck 2013-06-05 12:31:59 -07:00
commit 17b2b94a22
146 changed files with 14559 additions and 3930 deletions

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2005, 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@
FILES_export = \ FILES_export = \
sun/management/ClassLoadingImpl.java \ sun/management/ClassLoadingImpl.java \
sun/management/DiagnosticCommandImpl.java \
sun/management/FileSystemImpl.java \ sun/management/FileSystemImpl.java \
sun/management/Flag.java \ sun/management/Flag.java \
sun/management/GarbageCollectorImpl.java \ sun/management/GarbageCollectorImpl.java \

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2005, 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
FILES_c = \ FILES_c = \
ClassLoadingImpl.c \ ClassLoadingImpl.c \
DiagnosticCommandImpl.c \
FileSystemImpl.c \ FileSystemImpl.c \
Flag.c \ Flag.c \
GarbageCollectorImpl.c \ GarbageCollectorImpl.c \

View File

@ -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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize; Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize; Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass; Java_sun_management_ClassLoadingImpl_setVerboseClass;
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0; Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames; Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags; Java_sun_management_Flag_getFlags;

View File

@ -5,6 +5,8 @@
# (2)Added 2 new codepoints (KS X 1001:1998) # (2)Added 2 new codepoints (KS X 1001:1998)
# 0xA2E6 0x20AC # EURO Sign # 0xA2E6 0x20AC # EURO Sign
# 0xA2E7 0x00AE # Registered Sign # 0xA2E7 0x00AE # Registered Sign
# (3) KS X 1001:2002
# 0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI (Postal Code Mark)
# #
0x00 0x0000 0x00 0x0000
0x01 0x0001 0x01 0x0001
@ -295,6 +297,7 @@
# #
0xA2E6 0x20AC # EURO Sign 0xA2E6 0x20AC # EURO Sign
0xA2E7 0x00AE # Registered Sign 0xA2E7 0x00AE # Registered Sign
0xA2E8 0x327E # CIRCLED KOREAN CHARACTER JUEUI
# #
0xA2E0 0x2116 # NUMERO SIGN 0xA2E0 0x2116 # NUMERO SIGN
0xA2E1 0x33C7 # SQUARE CO 0xA2E1 0x33C7 # SQUARE CO

View File

@ -39,6 +39,7 @@
package build.tools.generatebreakiteratordata; package build.tools.generatebreakiteratordata;
import java.util.Arrays;
import java.util.Hashtable; import java.util.Hashtable;
/** /**
@ -701,7 +702,14 @@ class CharSet {
* the exact same characters as this one * the exact same characters as this one
*/ */
public boolean equals(Object that) { public boolean equals(Object that) {
return (that instanceof CharSet) && chars.equals(((CharSet)that).chars); return (that instanceof CharSet) && Arrays.equals(chars, ((CharSet)that).chars);
}
/**
* Returns the hash code for this set of characters
*/
public int hashCode() {
return Arrays.hashCode(chars);
} }
/** /**

View File

@ -342,7 +342,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC,\
DISABLE_SJAVAC:=true,\ DISABLE_SJAVAC:=true,\
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \ SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \ $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc, \ $(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc,\ INCLUDES := com/apple/jobjc,\
EXCLUDES := tests/java/com/apple/jobjc,\ EXCLUDES := tests/java/com/apple/jobjc,\
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\ BIN:=$(JDK_OUTPUTDIR)/jobjc_classes,\
@ -355,7 +355,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS,\
SETUP:=GENERATE_JDKBYTECODE,\ SETUP:=GENERATE_JDKBYTECODE,\
SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \ SRC:=$(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \ $(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
$(JDK_OUTPUTDIR)/gensrc, \ $(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
INCLUDES := com/apple/jobjc,\ INCLUDES := com/apple/jobjc,\
EXCLUDES := tests/java/com/apple/jobjc,\ EXCLUDES := tests/java/com/apple/jobjc,\
BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\ BIN:=$(JDK_OUTPUTDIR)/jobjc_classes_headers,\

View File

@ -69,6 +69,9 @@ define typesAndBits
$1_fulltype := character $1_fulltype := character
$1_Fulltype := Character $1_Fulltype := Character
$1_category := integralType $1_category := integralType
$1_streams := streamableType
$1_streamtype := int
$1_Streamtype := Int
$1_LBPV := 1 $1_LBPV := 1
endif endif
@ -97,7 +100,7 @@ define typesAndBits
$1_Type := Long $1_Type := Long
$1_fulltype := long $1_fulltype := long
$1_Fulltype := Long $1_Fulltype := Long
$1_category := integralType $1_category := integralType
$1_LBPV := 3 $1_LBPV := 3
endif endif
@ -231,10 +234,13 @@ $$($1_DST) : $$($1_DEP) $(GENSRC_BUFFER_DST)/_the.buffer.dir
$(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \ $(TOOL_SPP) < $$($1_SRC) > $$($1_OUT).tmp \
-K$$($1_type) \ -K$$($1_type) \
-K$$($1_category) \ -K$$($1_category) \
-K$$($1_streams) \
-Dtype=$$($1_type) \ -Dtype=$$($1_type) \
-DType=$$($1_Type) \ -DType=$$($1_Type) \
-Dfulltype=$$($1_fulltype) \ -Dfulltype=$$($1_fulltype) \
-DFulltype=$$($1_Fulltype) \ -DFulltype=$$($1_Fulltype) \
-Dstreamtype=$$($1_streamtype) \
-DStreamtype=$$($1_Streamtype) \
-Dx=$$($1_x) \ -Dx=$$($1_x) \
-Dmemtype=$$($1_memtype) \ -Dmemtype=$$($1_memtype) \
-DMemtype=$$($1_Memtype) \ -DMemtype=$$($1_Memtype) \

View File

@ -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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,10 @@ SUNWprivate_1.1 {
Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize; Java_com_sun_management_UnixOperatingSystem_getTotalSwapSpaceSize;
Java_com_sun_management_UnixOperatingSystem_initialize; Java_com_sun_management_UnixOperatingSystem_initialize;
Java_sun_management_ClassLoadingImpl_setVerboseClass; Java_sun_management_ClassLoadingImpl_setVerboseClass;
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
Java_sun_management_FileSystemImpl_isAccessUserOnly0; Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_Flag_getAllFlagNames; Java_sun_management_Flag_getAllFlagNames;
Java_sun_management_Flag_getFlags; Java_sun_management_Flag_getFlags;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -403,8 +403,9 @@ extends KeyAgreementSpi {
} }
return skey; return skey;
} else if (algorithm.equals("TlsPremasterSecret")) { } else if (algorithm.equals("TlsPremasterSecret")) {
// return entire secret // remove leading zero bytes per RFC 5246 Section 8.1.2
return new SecretKeySpec(secret, "TlsPremasterSecret"); return new SecretKeySpec(
KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
} else { } else {
throw new NoSuchAlgorithmException("Unsupported secret key " throw new NoSuchAlgorithmException("Unsupported secret key "
+ "algorithm: "+ algorithm); + "algorithm: "+ algorithm);

View File

@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore {
throw new InvalidKeyException("SecretKey of PBE type required"); throw new InvalidKeyException("SecretKey of PBE type required");
} }
if (params == null) { if (params == null) {
// generate default for salt and iteration count if necessary // should not auto-generate default values since current
if (salt == null) { // javax.crypto.Mac api does not have any method for caller to
salt = new byte[20]; // retrieve the generated defaults.
SunJCE.getRandom().nextBytes(salt); if ((salt == null) || (iCount == 0)) {
throw new InvalidAlgorithmParameterException
("PBEParameterSpec required for salt and iteration count");
} }
if (iCount == 0) iCount = 100;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("PBEParameterSpec type required"); ("PBEParameterSpec type required");

View File

@ -42,12 +42,10 @@ import java.security.spec.*;
*/ */
abstract class PBMAC1Core extends HmacCore { abstract class PBMAC1Core extends HmacCore {
private static final int DEFAULT_SALT_LENGTH = 20; // NOTE: this class inherits the Cloneable interface from HmacCore
private static final int DEFAULT_COUNT = 4096; // Need to override clone() if mutable fields are added.
private final String kdfAlgo; private final String kdfAlgo;
private final String hashAlgo; private final String hashAlgo;
private final PBKDF2Core kdf;
private final int blockLength; // in octets private final int blockLength; // in octets
/** /**
@ -56,13 +54,15 @@ abstract class PBMAC1Core extends HmacCore {
*/ */
PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength) PBMAC1Core(String kdfAlgo, String hashAlgo, int blockLength)
throws NoSuchAlgorithmException { throws NoSuchAlgorithmException {
super(hashAlgo, blockLength); super(hashAlgo, blockLength);
this.kdfAlgo = kdfAlgo; this.kdfAlgo = kdfAlgo;
this.hashAlgo = hashAlgo; this.hashAlgo = hashAlgo;
this.blockLength = blockLength; this.blockLength = blockLength;
}
switch(kdfAlgo) { private static PBKDF2Core getKDFImpl(String algo) {
PBKDF2Core kdf = null;
switch(algo) {
case "HmacSHA1": case "HmacSHA1":
kdf = new PBKDF2Core.HmacSHA1(); kdf = new PBKDF2Core.HmacSHA1();
break; break;
@ -79,9 +79,10 @@ abstract class PBMAC1Core extends HmacCore {
kdf = new PBKDF2Core.HmacSHA512(); kdf = new PBKDF2Core.HmacSHA512();
break; break;
default: default:
throw new NoSuchAlgorithmException( throw new ProviderException(
"No MAC implementation for " + kdfAlgo); "No MAC implementation for " + algo);
} }
return kdf;
} }
/** /**
@ -120,12 +121,13 @@ abstract class PBMAC1Core extends HmacCore {
throw new InvalidKeyException("SecretKey of PBE type required"); throw new InvalidKeyException("SecretKey of PBE type required");
} }
if (params == null) { if (params == null) {
// generate default for salt and iteration count if necessary // should not auto-generate default values since current
if (salt == null) { // javax.crypto.Mac api does not have any method for caller to
salt = new byte[DEFAULT_SALT_LENGTH]; // retrieve the generated defaults.
SunJCE.getRandom().nextBytes(salt); if ((salt == null) || (iCount == 0)) {
throw new InvalidAlgorithmParameterException
("PBEParameterSpec required for salt and iteration count");
} }
if (iCount == 0) iCount = DEFAULT_COUNT;
} else if (!(params instanceof PBEParameterSpec)) { } else if (!(params instanceof PBEParameterSpec)) {
throw new InvalidAlgorithmParameterException throw new InvalidAlgorithmParameterException
("PBEParameterSpec type required"); ("PBEParameterSpec type required");
@ -168,7 +170,7 @@ abstract class PBMAC1Core extends HmacCore {
java.util.Arrays.fill(passwdChars, ' '); java.util.Arrays.fill(passwdChars, ' ');
SecretKey s = null; SecretKey s = null;
PBKDF2Core kdf = getKDFImpl(kdfAlgo);
try { try {
s = kdf.engineGenerateSecret(pbeSpec); s = kdf.engineGenerateSecret(pbeSpec);

View File

@ -731,10 +731,11 @@ public final class SunJCE extends Provider {
put("Mac.HmacSHA384 SupportedKeyFormats", "RAW"); put("Mac.HmacSHA384 SupportedKeyFormats", "RAW");
put("Mac.HmacSHA512 SupportedKeyFormats", "RAW"); put("Mac.HmacSHA512 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW"); put("Mac.HmacPBESHA1 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA224 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA1 SupportedKeyFormatS", "RAW");
put("Mac.HmacPBESHA256 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA224 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA384 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA256 SupportedKeyFormats", "RAW");
put("Mac.HmacPBESHA512 SupportedKeyFormats", "RAW"); put("Mac.PBEWithHmacSHA384 SupportedKeyFormats", "RAW");
put("Mac.PBEWithHmacSHA512 SupportedKeyFormats", "RAW");
put("Mac.SslMacMD5 SupportedKeyFormats", "RAW"); put("Mac.SslMacMD5 SupportedKeyFormats", "RAW");
put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW"); put("Mac.SslMacSHA1 SupportedKeyFormats", "RAW");

View File

@ -0,0 +1,220 @@
/*
* 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 com.sun.management;
import java.lang.management.PlatformManagedObject;
import javax.management.DynamicMBean;
/**
* Management interface for the diagnostic commands for the HotSpot Virtual Machine.
*
* <p>The {code DiagnosticCommandMBean} is registered to the
* {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
* platform MBeanServer} as are other platform MBeans.
*
* <p>The {@link javax.management.ObjectName ObjectName} for uniquely identifying
* the diagnostic MBean within an MBeanServer is:
* <blockquote>
* {@code com.sun.management:type=DiagnosticCommand}
* </blockquote>
*
* <p>This MBean is a {@link javax.management.DynamicMBean DynamicMBean}
* and also a {@link javax.management.NotificationEmitter}.
* The {@code DiagnosticCommandMBean} is generated at runtime and is subject to
* modifications during the lifetime of the Java virtual machine.
*
* A <em>diagnostic command</em> is represented as an operation of
* the {@code DiagnosticCommandMBean} interface. Each diagnostic command has:
* <ul>
* <li>the diagnostic command name which is the name being referenced in
* the HotSpot Virtual Machine</li>
* <li>the MBean operation name which is the
* {@linkplain javax.management.MBeanOperationInfo#getName() name}
* generated for the diagnostic command operation invocation.
* The MBean operation name is implementation dependent</li>
* </ul>
*
* The recommended way to transform a diagnostic command name into a MBean
* operation name is as follows:
* <ul>
* <li>All characters from the first one to the first dot are set to be
* lower-case characters</li>
* <li>Every dot or underline character is removed and the following
* character is set to be an upper-case character</li>
* <li>All other characters are copied without modification</li>
* </ul>
*
* <p>The diagnostic command name is always provided with the meta-data on the
* operation in a field named {@code dcmd.name} (see below).
*
* <p>A diagnostic command may or may not support options or arguments.
* All the operations return {@code String} and either take
* no parameter for operations that do not support any option or argument,
* or take a {@code String[]} parameter for operations that support at least
* one option or argument.
* Each option or argument must be stored in a single String.
* Options or arguments split across several String instances are not supported.
*
* <p>The distinction between options and arguments: options are identified by
* the option name while arguments are identified by their position in the
* command line. Options and arguments are processed in the order of the array
* passed to the invocation method.
*
* <p>Like any operation of a dynamic MBean, each of these operations is
* described by {@link javax.management.MBeanOperationInfo MBeanOperationInfo}
* instance. Here's the values returned by this object:
* <ul>
* <li>{@link javax.management.MBeanOperationInfo#getName() getName()}
* returns the operation name generated from the diagnostic command name</li>
* <li>{@link javax.management.MBeanOperationInfo#getDescription() getDescription()}
* returns the diagnostic command description
* (the same as the one return in the 'help' command)</li>
* <li>{@link javax.management.MBeanOperationInfo#getImpact() getImpact()}
* returns <code>ACTION_INFO</code></li>
* <li>{@link javax.management.MBeanOperationInfo#getReturnType() getReturnType()}
* returns {@code java.lang.String}</li>
* <li>{@link javax.management.MBeanOperationInfo#getDescriptor() getDescriptor()}
* returns a Descriptor instance (see below)</li>
* </ul>
*
* <p>The {@link javax.management.Descriptor Descriptor}
* is a collection of fields containing additional
* meta-data for a JMX element. A field is a name and an associated value.
* The additional meta-data provided for an operation associated with a
* diagnostic command are described in the table below:
* <p>
*
* <table border="1" cellpadding="5">
* <tr>
* <th>Name</th><th>Type</th><th>Description</th>
* </tr>
* <tr>
* <td>dcmd.name</td><td>String</td>
* <td>The original diagnostic command name (not the operation name)</td>
* </tr>
* <tr>
* <td>dcmd.description</td><td>String</td>
* <td>The diagnostic command description</td>
* </tr>
* <tr>
* <td>dcmd.help</td><td>String</td>
* <td>The full help message for this diagnostic command (same output as
* the one produced by the 'help' command)</td>
* </tr>
* <tr>
* <td>dcmd.vmImpact</td><td>String</td>
* <td>The impact of the diagnostic command,
* this value is the same as the one printed in the 'impact'
* section of the help message of the diagnostic command, and it
* is different from the getImpact() of the MBeanOperationInfo</td>
* </tr>
* <tr>
* <td>dcmd.enabled</td><td>boolean</td>
* <td>True if the diagnostic command is enabled, false otherwise</td>
* </tr>
* <tr>
* <td>dcmd.permissionClass</td><td>String</td>
* <td>Some diagnostic command might require a specific permission to be
* executed, in addition to the MBeanPermission to invoke their
* associated MBean operation. This field returns the fully qualified
* name of the permission class or null if no permission is required
* </td>
* </tr>
* <tr>
* <td>dcmd.permissionName</td><td>String</td>
* <td>The fist argument of the permission required to execute this
* diagnostic command or null if no permission is required</td>
* </tr>
* <tr>
* <td>dcmd.permissionAction</td><td>String</td>
* <td>The second argument of the permission required to execute this
* diagnostic command or null if the permission constructor has only
* one argument (like the ManagementPermission) or if no permission
* is required</td>
* </tr>
* <tr>
* <td>dcmd.arguments</td><td>Descriptor</td>
* <td>A Descriptor instance containing the descriptions of options and
* arguments supported by the diagnostic command (see below)</td>
* </tr>
* </table>
* <p>
*
* <p>The description of parameters (options or arguments) of a diagnostic
* command is provided within a Descriptor instance. In this Descriptor,
* each field name is a parameter name, and each field value is itself
* a Descriptor instance. The fields provided in this second Descriptor
* instance are described in the table below:
*
* <table border="1" cellpadding="5">
* <tr>
* <th>Name</th><th>Type</th><th>Description</th>
* </tr>
* <tr>
* <td>dcmd.arg.name</td><td>String</td>
* <td>The name of the parameter</td>
* </tr>
* <tr>
* <td>dcmd.arg.type</td><td>String</td>
* <td>The type of the parameter. The returned String is the name of a type
* recognized by the diagnostic command parser. These types are not
* Java types and are implementation dependent.
* </td>
* </tr>
* <tr>
* <td>dcmd.arg.description</td><td>String</td>
* <td>The parameter description</td>
* </tr>
* <tr>
* <td>dcmd.arg.isMandatory</td><td>boolean</td>
* <td>True if the parameter is mandatory, false otherwise</td>
* </tr>
* <tr>
* <td>dcmd.arg.isOption</td><td>boolean</td>
* <td>True if the parameter is an option, false if it is an argument</td>
* </tr>
* <tr>
* <td>dcmd.arg.isMultiple</td><td>boolean</td>
* <td>True if the parameter can be specified several times, false
* otherwise</td>
* </tr>
* </table>
*
* <p>When the set of diagnostic commands currently supported by the Java
* Virtual Machine is modified, the {@code DiagnosticCommandMBean} emits
* a {@link javax.management.Notification} with a
* {@linkplain javax.management.Notification#getType() type} of
* <a href="{@docRoot}/../../../../api/javax/management/MBeanInfo.html#info-changed">
* {@code "jmx.mbean.info.changed"}</a> and a
* {@linkplain javax.management.Notification#getUserData() userData} that
* is the new {@code MBeanInfo}.
*
* @since 8
*/
public interface DiagnosticCommandMBean extends DynamicMBean
{
}

View File

@ -26,7 +26,6 @@
package java.lang; package java.lang;
import java.lang.annotation.Native; import java.lang.annotation.Native;
import java.util.Properties;
/** /**
* The {@code Integer} class wraps a value of the primitive type * The {@code Integer} class wraps a value of the primitive type
@ -185,7 +184,7 @@ public final class Integer extends Number implements Comparable<Integer> {
* @since 1.8 * @since 1.8
*/ */
public static String toUnsignedString(int i, int radix) { public static String toUnsignedString(int i, int radix) {
return Long.toString(toUnsignedLong(i), radix); return Long.toUnsignedString(toUnsignedLong(i), radix);
} }
/** /**
@ -307,20 +306,39 @@ public final class Integer extends Number implements Comparable<Integer> {
/** /**
* Convert the integer to an unsigned number. * Convert the integer to an unsigned number.
*/ */
private static String toUnsignedString0(int i, int shift) { private static String toUnsignedString0(int val, int shift) {
char[] buf = new char[32]; // assert shift > 0 && shift <=5 : "Illegal shift value";
int charPos = 32; int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
// Use special constructor which takes over "buf".
return new String(buf, true);
}
/**
* Format a long (treated as unsigned) into a character buffer.
* @param val the unsigned int to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = 1 << shift; int radix = 1 << shift;
int mask = radix - 1; int mask = radix - 1;
do { do {
buf[--charPos] = digits[i & mask]; buf[offset + --charPos] = Integer.digits[val & mask];
i >>>= shift; val >>>= shift;
} while (i != 0); } while (val != 0 && charPos > 0);
return new String(buf, charPos, (32 - charPos)); return charPos;
} }
final static char [] DigitTens = { final static char [] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
@ -875,6 +893,7 @@ public final class Integer extends Number implements Comparable<Integer> {
* Returns the value of this {@code Integer} as a {@code long} * Returns the value of this {@code Integer} as a {@code long}
* after a widening primitive conversion. * after a widening primitive conversion.
* @jls 5.1.2 Widening Primitive Conversions * @jls 5.1.2 Widening Primitive Conversions
* @see Integer#toUnsignedLong(int)
*/ */
public long longValue() { public long longValue() {
return (long)value; return (long)value;

View File

@ -28,6 +28,7 @@ package java.lang;
import java.lang.annotation.Native; import java.lang.annotation.Native;
import java.math.*; import java.math.*;
/** /**
* The {@code Long} class wraps a value of the primitive type {@code * The {@code Long} class wraps a value of the primitive type {@code
* long} in an object. An object of type {@code Long} contains a * long} in an object. An object of type {@code Long} contains a
@ -344,18 +345,39 @@ public final class Long extends Number implements Comparable<Long> {
} }
/** /**
* Convert the integer to an unsigned number. * Format a long (treated as unsigned) into a String.
* @param val the value to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
*/ */
private static String toUnsignedString0(long i, int shift) { static String toUnsignedString0(long val, int shift) {
char[] buf = new char[64]; // assert shift > 0 && shift <=5 : "Illegal shift value";
int charPos = 64; int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedLong(val, shift, buf, 0, chars);
return new String(buf, true);
}
/**
* Format a long (treated as unsigned) into a character buffer.
* @param val the unsigned long to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
int charPos = len;
int radix = 1 << shift; int radix = 1 << shift;
long mask = radix - 1; int mask = radix - 1;
do { do {
buf[--charPos] = Integer.digits[(int)(i & mask)]; buf[offset + --charPos] = Integer.digits[((int) val) & mask];
i >>>= shift; val >>>= shift;
} while (i != 0); } while (val != 0 && charPos > 0);
return new String(buf, charPos, (64 - charPos));
return charPos;
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,9 @@ import javax.management.StandardMBean;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.security.AccessController; import java.security.AccessController;
import java.security.Permission; import java.security.Permission;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -482,6 +484,11 @@ public class ManagementFactory {
} }
} }
} }
HashMap<ObjectName, DynamicMBean> dynmbeans =
ManagementFactoryHelper.getPlatformDynamicMBeans();
for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
}
} }
return platformMBeanServer; return platformMBeanServer;
} }
@ -825,4 +832,24 @@ public class ManagementFactory {
} }
} }
/**
* Registers a DynamicMBean.
*/
private static void addDynamicMBean(final MBeanServer mbs,
final DynamicMBean dmbean,
final ObjectName on) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
mbs.registerMBean(dmbean, on);
return null;
}
});
} catch (PrivilegedActionException e) {
throw new RuntimeException(e.getException());
}
}
} }

View File

@ -128,8 +128,7 @@ public final class HttpCookie implements Cloneable {
* a {@code String} specifying the value of the cookie * a {@code String} specifying the value of the cookie
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the cookie name contains illegal characters or it is one of * if the cookie name contains illegal characters
* the tokens reserved for use by the cookie protocol
* @throws NullPointerException * @throws NullPointerException
* if {@code name} is {@code null} * if {@code name} is {@code null}
* *
@ -142,7 +141,7 @@ public final class HttpCookie implements Cloneable {
private HttpCookie(String name, String value, String header) { private HttpCookie(String name, String value, String header) {
name = name.trim(); name = name.trim();
if (name.length() == 0 || !isToken(name)) { if (name.length() == 0 || !isToken(name) || name.charAt(0) == '$') {
throw new IllegalArgumentException("Illegal cookie name"); throw new IllegalArgumentException("Illegal cookie name");
} }
@ -170,9 +169,8 @@ public final class HttpCookie implements Cloneable {
* @return a List of cookie parsed from header line string * @return a List of cookie parsed from header line string
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if header string violates the cookie specification's syntax, or * if header string violates the cookie specification's syntax or
* the cookie name contains illegal characters, or the cookie name * the cookie name contains illegal characters.
* is one of the tokens reserved for use by the cookie protocol
* @throws NullPointerException * @throws NullPointerException
* if the header string is {@code null} * if the header string is {@code null}
*/ */

View File

@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission {
throw new IllegalArgumentException ("unexpected URL scheme"); throw new IllegalArgumentException ("unexpected URL scheme");
} }
if (!u.getSchemeSpecificPart().equals("*")) { if (!u.getSchemeSpecificPart().equals("*")) {
u = URI.create(scheme + "://" + u.getAuthority() + u.getPath()); u = URI.create(scheme + "://" + u.getRawAuthority() + u.getRawPath());
} }
return u; return u;
} }

View File

@ -25,6 +25,7 @@
package java.nio; package java.nio;
import java.util.Spliterator;
/** /**
* A container for data of a specific primitive type. * A container for data of a specific primitive type.
@ -173,6 +174,13 @@ package java.nio;
public abstract class Buffer { public abstract class Buffer {
/**
* The characteristics of Spliterators that traverse and split elements
* maintained in Buffers.
*/
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
// Invariants: mark <= position <= limit <= capacity // Invariants: mark <= position <= limit <= capacity
private int mark = -1; private int mark = -1;
private int position = 0; private int position = 0;

View File

@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
return Bits.get$Type$$BO$(bb, ix(checkIndex(i))); return Bits.get$Type$$BO$(bb, ix(checkIndex(i)));
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return Bits.get$Type$$BO$(bb, ix(i));
}
#end[streamableType]
#end[rw] #end[rw]
public $Type$Buffer put($type$ x) { public $Type$Buffer put($type$ x) {

View File

@ -0,0 +1,96 @@
/*
* 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.nio;
import java.util.Comparator;
import java.util.Spliterator;
import java.util.function.IntConsumer;
/**
* A Spliterator.OfInt for sources that traverse and split elements
* maintained in a CharBuffer.
*
* @implNote
* The implementation is based on the code for the Array-based spliterators.
*/
class CharBufferSpliterator implements Spliterator.OfInt {
private final CharBuffer buffer;
private int index; // current index, modified on advance/split
private final int limit;
CharBufferSpliterator(CharBuffer buffer) {
this(buffer, buffer.position(), buffer.limit());
}
CharBufferSpliterator(CharBuffer buffer, int origin, int limit) {
assert origin <= limit;
this.buffer = buffer;
this.index = (origin <= limit) ? origin : limit;
this.limit = limit;
}
@Override
public OfInt trySplit() {
int lo = index, mid = (lo + limit) >>> 1;
return (lo >= mid)
? null
: new CharBufferSpliterator(buffer, lo, index = mid);
}
@Override
public void forEachRemaining(IntConsumer action) {
if (action == null)
throw new NullPointerException();
CharBuffer cb = buffer;
int i = index;
int hi = limit;
index = hi;
while (i < hi) {
action.accept(cb.getUnchecked(i++));
}
}
@Override
public boolean tryAdvance(IntConsumer action) {
if (action == null)
throw new NullPointerException();
if (index >= 0 && index < limit) {
action.accept(buffer.getUnchecked(index++));
return true;
}
return false;
}
@Override
public long estimateSize() {
return (long)(limit - index);
}
@Override
public int characteristics() {
return Buffer.SPLITERATOR_CHARACTERISTICS;
}
}

View File

@ -253,6 +253,12 @@ class Direct$Type$Buffer$RW$$BO$
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i))))); return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
}
#end[streamableType]
public $Type$Buffer get($type$[] dst, int offset, int length) { public $Type$Buffer get($type$[] dst, int offset, int length) {
#if[rw] #if[rw]
if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) { if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {

View File

@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$
return hb[ix(checkIndex(i))]; return hb[ix(checkIndex(i))];
} }
#if[streamableType]
$type$ getUnchecked(int i) {
return hb[ix(i)];
}
#end[streamableType]
public $Type$Buffer get($type$[] dst, int offset, int length) { public $Type$Buffer get($type$[] dst, int offset, int length) {
checkBounds(offset, length, dst.length); checkBounds(offset, length, dst.length);
if (length > remaining()) if (length > remaining())

View File

@ -77,6 +77,10 @@ class StringCharBuffer // package-private
return str.charAt(checkIndex(index) + offset); return str.charAt(checkIndex(index) + offset);
} }
char getUnchecked(int index) {
return str.charAt(index + offset);
}
// ## Override bulk get methods for better performance // ## Override bulk get methods for better performance
public final CharBuffer put(char c) { public final CharBuffer put(char c) {

View File

@ -30,6 +30,11 @@ package java.nio;
#if[char] #if[char]
import java.io.IOException; import java.io.IOException;
#end[char] #end[char]
#if[streamableType]
import java.util.Spliterator;
import java.util.stream.StreamSupport;
import java.util.stream.$Streamtype$Stream;
#end[streamableType]
/** /**
* $A$ $type$ buffer. * $A$ $type$ buffer.
@ -589,6 +594,19 @@ public abstract class $Type$Buffer
*/ */
public abstract $type$ get(int index); public abstract $type$ get(int index);
#if[streamableType]
/**
* Absolute <i>get</i> method. Reads the $type$ at the given
* index without any validation of the index.
*
* @param index
* The index from which the $type$ will be read
*
* @return The $type$ at the given index
*/
abstract $type$ getUnchecked(int index); // package-private
#end[streamableType]
/** /**
* Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>. * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
* *
@ -1458,4 +1476,16 @@ public abstract class $Type$Buffer
#end[byte] #end[byte]
#if[streamableType]
#if[char]
@Override
#end[char]
public $Streamtype$Stream $type$s() {
return StreamSupport.$streamtype$Stream(() -> new $Type$BufferSpliterator(this),
Buffer.SPLITERATOR_CHARACTERISTICS);
}
#end[streamableType]
} }

View File

@ -85,6 +85,15 @@ public final class AccessControlContext {
private DomainCombiner combiner = null; private DomainCombiner combiner = null;
// limited privilege scope
private Permission permissions[];
private AccessControlContext parent;
private boolean isWrapped;
// is constrained by limited privilege scope?
private boolean isLimited;
private ProtectionDomain limitedContext[];
private static boolean debugInit = false; private static boolean debugInit = false;
private static Debug debug = null; private static Debug debug = null;
@ -178,14 +187,79 @@ public final class AccessControlContext {
/** /**
* package private for AccessController * package private for AccessController
*
* This "argument wrapper" context will be passed as the actual context
* parameter on an internal doPrivileged() call used in the implementation.
*/ */
AccessControlContext(ProtectionDomain context[], DomainCombiner combiner) { AccessControlContext(ProtectionDomain caller, DomainCombiner combiner,
AccessControlContext parent, AccessControlContext context,
Permission[] perms)
{
/*
* Combine the domains from the doPrivileged() context into our
* wrapper context, if necessary.
*/
ProtectionDomain[] callerPDs = null;
if (caller != null) {
callerPDs = new ProtectionDomain[] { caller };
}
if (context != null) { if (context != null) {
this.context = context.clone(); if (combiner != null) {
this.context = combiner.combine(callerPDs, context.context);
} else {
this.context = combine(callerPDs, context.context);
}
} else {
/*
* Call combiner even if there is seemingly nothing to combine.
*/
if (combiner != null) {
this.context = combiner.combine(callerPDs, null);
} else {
this.context = combine(callerPDs, null);
}
} }
this.combiner = combiner; this.combiner = combiner;
Permission[] tmp = null;
if (perms != null) {
tmp = new Permission[perms.length];
for (int i=0; i < perms.length; i++) {
if (perms[i] == null) {
throw new NullPointerException("permission can't be null");
}
/*
* An AllPermission argument is equivalent to calling
* doPrivileged() without any limit permissions.
*/
if (perms[i].getClass() == AllPermission.class) {
parent = null;
}
tmp[i] = perms[i];
}
}
/*
* For a doPrivileged() with limited privilege scope, initialize
* the relevant fields.
*
* The limitedContext field contains the union of all domains which
* are enclosed by this limited privilege scope. In other words,
* it contains all of the domains which could potentially be checked
* if none of the limiting permissions implied a requested permission.
*/
if (parent != null) {
this.limitedContext = combine(parent.context, parent.limitedContext);
this.isLimited = true;
this.isWrapped = true;
this.permissions = tmp;
this.parent = parent;
this.privilegedContext = context; // used in checkPermission2()
}
} }
/** /**
* package private constructor for AccessController.getContext() * package private constructor for AccessController.getContext()
*/ */
@ -260,6 +334,13 @@ public final class AccessControlContext {
if (sm != null) { if (sm != null) {
sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION); sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION);
} }
return getCombiner();
}
/**
* package private for AccessController
*/
DomainCombiner getCombiner() {
return combiner; return combiner;
} }
@ -335,8 +416,10 @@ public final class AccessControlContext {
or the first domain was a Privileged system domain. This or the first domain was a Privileged system domain. This
is to make the common case for system code very fast */ is to make the common case for system code very fast */
if (context == null) if (context == null) {
checkPermission2(perm);
return; return;
}
for (int i=0; i< context.length; i++) { for (int i=0; i< context.length; i++) {
if (context[i] != null && !context[i].implies(perm)) { if (context[i] != null && !context[i].implies(perm)) {
@ -370,20 +453,108 @@ public final class AccessControlContext {
debug.println("access allowed "+perm); debug.println("access allowed "+perm);
} }
return; checkPermission2(perm);
}
/*
* Check the domains associated with the limited privilege scope.
*/
private void checkPermission2(Permission perm) {
if (!isLimited) {
return;
}
/*
* Check the doPrivileged() context parameter, if present.
*/
if (privilegedContext != null) {
privilegedContext.checkPermission2(perm);
}
/*
* Ignore the limited permissions and parent fields of a wrapper
* context since they were already carried down into the unwrapped
* context.
*/
if (isWrapped) {
return;
}
/*
* Try to match any limited privilege scope.
*/
if (permissions != null) {
Class<?> permClass = perm.getClass();
for (int i=0; i < permissions.length; i++) {
Permission limit = permissions[i];
if (limit.getClass().equals(permClass) && limit.implies(perm)) {
return;
}
}
}
/*
* Check the limited privilege scope up the call stack or the inherited
* parent thread call stack of this ACC.
*/
if (parent != null) {
/*
* As an optimization, if the parent context is the inherited call
* stack context from a parent thread then checking the protection
* domains of the parent context is redundant since they have
* already been merged into the child thread's context by
* optimize(). When parent is set to an inherited context this
* context was not directly created by a limited scope
* doPrivileged() and it does not have its own limited permissions.
*/
if (permissions == null) {
parent.checkPermission2(perm);
} else {
parent.checkPermission(perm);
}
}
} }
/** /**
* Take the stack-based context (this) and combine it with the * Take the stack-based context (this) and combine it with the
* privileged or inherited context, if need be. * privileged or inherited context, if need be. Any limited
* privilege scope is flagged regardless of whether the assigned
* context comes from an immediately enclosing limited doPrivileged().
* The limited privilege scope can indirectly flow from the inherited
* parent thread or an assigned context previously captured by getContext().
*/ */
AccessControlContext optimize() { AccessControlContext optimize() {
// the assigned (privileged or inherited) context // the assigned (privileged or inherited) context
AccessControlContext acc; AccessControlContext acc;
DomainCombiner combiner = null;
AccessControlContext parent = null;
Permission[] permissions = null;
if (isPrivileged) { if (isPrivileged) {
acc = privilegedContext; acc = privilegedContext;
if (acc != null) {
/*
* If the context is from a limited scope doPrivileged() then
* copy the permissions and parent fields out of the wrapper
* context that was created to hold them.
*/
if (acc.isWrapped) {
permissions = acc.permissions;
parent = acc.parent;
}
}
} else { } else {
acc = AccessController.getInheritedAccessControlContext(); acc = AccessController.getInheritedAccessControlContext();
if (acc != null) {
/*
* If the inherited context is constrained by a limited scope
* doPrivileged() then set it as our parent so we will process
* the non-domain-related state.
*/
if (acc.isLimited) {
parent = acc;
}
}
} }
// this.context could be null if only system code is on the stack; // this.context could be null if only system code is on the stack;
@ -393,53 +564,98 @@ public final class AccessControlContext {
// acc.context could be null if only system code was involved; // acc.context could be null if only system code was involved;
// in that case, ignore the assigned context // in that case, ignore the assigned context
boolean skipAssigned = (acc == null || acc.context == null); boolean skipAssigned = (acc == null || acc.context == null);
ProtectionDomain[] assigned = (skipAssigned) ? null : acc.context;
ProtectionDomain[] pd;
// if there is no enclosing limited privilege scope on the stack or
// inherited from a parent thread
boolean skipLimited = ((acc == null || !acc.isWrapped) && parent == null);
if (acc != null && acc.combiner != null) { if (acc != null && acc.combiner != null) {
// let the assigned acc's combiner do its thing // let the assigned acc's combiner do its thing
return goCombiner(context, acc); if (getDebug() != null) {
debug.println("AccessControlContext invoking the Combiner");
}
// No need to clone current and assigned.context
// combine() will not update them
combiner = acc.combiner;
pd = combiner.combine(context, assigned);
} else {
if (skipStack) {
if (skipAssigned) {
calculateFields(acc, parent, permissions);
return this;
} else if (skipLimited) {
return acc;
}
} else if (assigned != null) {
if (skipLimited) {
// optimization: if there is a single stack domain and
// that domain is already in the assigned context; no
// need to combine
if (context.length == 1 && context[0] == assigned[0]) {
return acc;
}
}
}
pd = combine(context, assigned);
if (skipLimited && !skipAssigned && pd == assigned) {
return acc;
} else if (skipAssigned && pd == context) {
calculateFields(acc, parent, permissions);
return this;
}
} }
// optimization: if neither have contexts; return acc if possible // Reuse existing ACC
// rather than this, because acc might have a combiner this.context = pd;
if (skipAssigned && skipStack) { this.combiner = combiner;
return this; this.isPrivileged = false;
}
// optimization: if there is no stack context; there is no reason calculateFields(acc, parent, permissions);
// to compress the assigned context, it already is compressed return this;
if (skipStack) { }
return acc;
}
int slen = context.length;
/*
* Combine the current (stack) and assigned domains.
*/
private static ProtectionDomain[] combine(ProtectionDomain[]current,
ProtectionDomain[] assigned) {
// current could be null if only system code is on the stack;
// in that case, ignore the stack context
boolean skipStack = (current == null);
// assigned could be null if only system code was involved;
// in that case, ignore the assigned context
boolean skipAssigned = (assigned == null);
int slen = (skipStack) ? 0 : current.length;
// optimization: if there is no assigned context and the stack length // optimization: if there is no assigned context and the stack length
// is less then or equal to two; there is no reason to compress the // is less then or equal to two; there is no reason to compress the
// stack context, it already is // stack context, it already is
if (skipAssigned && slen <= 2) { if (skipAssigned && slen <= 2) {
return this; return current;
} }
// optimization: if there is a single stack domain and that domain int n = (skipAssigned) ? 0 : assigned.length;
// is already in the assigned context; no need to combine
if ((slen == 1) && (context[0] == acc.context[0])) {
return acc;
}
int n = (skipAssigned) ? 0 : acc.context.length;
// now we combine both of them, and create a new context // now we combine both of them, and create a new context
ProtectionDomain pd[] = new ProtectionDomain[slen + n]; ProtectionDomain pd[] = new ProtectionDomain[slen + n];
// first copy in the assigned context domains, no need to compress // first copy in the assigned context domains, no need to compress
if (!skipAssigned) { if (!skipAssigned) {
System.arraycopy(acc.context, 0, pd, 0, n); System.arraycopy(assigned, 0, pd, 0, n);
} }
// now add the stack context domains, discarding nulls and duplicates // now add the stack context domains, discarding nulls and duplicates
outer: outer:
for (int i = 0; i < context.length; i++) { for (int i = 0; i < slen; i++) {
ProtectionDomain sd = context[i]; ProtectionDomain sd = current[i];
if (sd != null) { if (sd != null) {
for (int j = 0; j < n; j++) { for (int j = 0; j < n; j++) {
if (sd == pd[j]) { if (sd == pd[j]) {
@ -453,54 +669,48 @@ public final class AccessControlContext {
// if length isn't equal, we need to shorten the array // if length isn't equal, we need to shorten the array
if (n != pd.length) { if (n != pd.length) {
// optimization: if we didn't really combine anything // optimization: if we didn't really combine anything
if (!skipAssigned && n == acc.context.length) { if (!skipAssigned && n == assigned.length) {
return acc; return assigned;
} else if (skipAssigned && n == slen) { } else if (skipAssigned && n == slen) {
return this; return current;
} }
ProtectionDomain tmp[] = new ProtectionDomain[n]; ProtectionDomain tmp[] = new ProtectionDomain[n];
System.arraycopy(pd, 0, tmp, 0, n); System.arraycopy(pd, 0, tmp, 0, n);
pd = tmp; pd = tmp;
} }
// return new AccessControlContext(pd, false); return pd;
// Reuse existing ACC
this.context = pd;
this.combiner = null;
this.isPrivileged = false;
return this;
} }
private AccessControlContext goCombiner(ProtectionDomain[] current,
AccessControlContext assigned) {
// the assigned ACC's combiner is not null -- /*
// let the combiner do its thing * Calculate the additional domains that could potentially be reached via
* limited privilege scope. Mark the context as being subject to limited
* privilege scope unless the reachable domains (if any) are already
* contained in this domain context (in which case any limited
* privilege scope checking would be redundant).
*/
private void calculateFields(AccessControlContext assigned,
AccessControlContext parent, Permission[] permissions)
{
ProtectionDomain[] parentLimit = null;
ProtectionDomain[] assignedLimit = null;
ProtectionDomain[] newLimit;
// XXX we could add optimizations to 'current' here ... parentLimit = (parent != null)? parent.limitedContext: null;
assignedLimit = (assigned != null)? assigned.limitedContext: null;
if (getDebug() != null) { newLimit = combine(parentLimit, assignedLimit);
debug.println("AccessControlContext invoking the Combiner"); if (newLimit != null) {
if (context == null || !containsAllPDs(newLimit, context)) {
this.limitedContext = newLimit;
this.permissions = permissions;
this.parent = parent;
this.isLimited = true;
}
} }
// No need to clone current and assigned.context
// combine() will not update them
ProtectionDomain[] combinedPds = assigned.combiner.combine(
current, assigned.context);
// return new AccessControlContext(combinedPds, assigned.combiner);
// Reuse existing ACC
this.context = combinedPds;
this.combiner = assigned.combiner;
this.isPrivileged = false;
return this;
} }
/** /**
* Checks two AccessControlContext objects for equality. * Checks two AccessControlContext objects for equality.
* Checks that <i>obj</i> is * Checks that <i>obj</i> is
@ -520,31 +730,131 @@ public final class AccessControlContext {
AccessControlContext that = (AccessControlContext) obj; AccessControlContext that = (AccessControlContext) obj;
if (!equalContext(that))
if (context == null) {
return (that.context == null);
}
if (that.context == null)
return false; return false;
if (!(this.containsAllPDs(that) && that.containsAllPDs(this))) if (!equalLimitedContext(that))
return false;
if (this.combiner == null)
return (that.combiner == null);
if (that.combiner == null)
return false;
if (!this.combiner.equals(that.combiner))
return false; return false;
return true; return true;
} }
private boolean containsAllPDs(AccessControlContext that) { /*
* Compare for equality based on state that is free of limited
* privilege complications.
*/
private boolean equalContext(AccessControlContext that) {
if (!equalPDs(this.context, that.context))
return false;
if (this.combiner == null && that.combiner != null)
return false;
if (this.combiner != null && !this.combiner.equals(that.combiner))
return false;
return true;
}
private boolean equalPDs(ProtectionDomain[] a, ProtectionDomain[] b) {
if (a == null) {
return (b == null);
}
if (b == null)
return false;
if (!(containsAllPDs(a, b) && containsAllPDs(b, a)))
return false;
return true;
}
/*
* Compare for equality based on state that is captured during a
* call to AccessController.getContext() when a limited privilege
* scope is in effect.
*/
private boolean equalLimitedContext(AccessControlContext that) {
if (that == null)
return false;
/*
* If neither instance has limited privilege scope then we're done.
*/
if (!this.isLimited && !that.isLimited)
return true;
/*
* If only one instance has limited privilege scope then we're done.
*/
if (!(this.isLimited && that.isLimited))
return false;
/*
* Wrapped instances should never escape outside the implementation
* this class and AccessController so this will probably never happen
* but it only makes any sense to compare if they both have the same
* isWrapped state.
*/
if ((this.isWrapped && !that.isWrapped) ||
(!this.isWrapped && that.isWrapped)) {
return false;
}
if (this.permissions == null && that.permissions != null)
return false;
if (this.permissions != null && that.permissions == null)
return false;
if (!(this.containsAllLimits(that) && that.containsAllLimits(this)))
return false;
/*
* Skip through any wrapped contexts.
*/
AccessControlContext thisNextPC = getNextPC(this);
AccessControlContext thatNextPC = getNextPC(that);
/*
* The protection domains and combiner of a privilegedContext are
* not relevant because they have already been included in the context
* of this instance by optimize() so we only care about any limited
* privilege state they may have.
*/
if (thisNextPC == null && thatNextPC != null && thatNextPC.isLimited)
return false;
if (thisNextPC != null && !thisNextPC.equalLimitedContext(thatNextPC))
return false;
if (this.parent == null && that.parent != null)
return false;
if (this.parent != null && !this.parent.equals(that.parent))
return false;
return true;
}
/*
* Follow the privilegedContext link making our best effort to skip
* through any wrapper contexts.
*/
private static AccessControlContext getNextPC(AccessControlContext acc) {
while (acc != null && acc.privilegedContext != null) {
acc = acc.privilegedContext;
if (!acc.isWrapped)
return acc;
}
return null;
}
private static boolean containsAllPDs(ProtectionDomain[] thisContext,
ProtectionDomain[] thatContext) {
boolean match = false; boolean match = false;
// //
// ProtectionDomains within an ACC currently cannot be null // ProtectionDomains within an ACC currently cannot be null
// and this is enforced by the constructor and the various // and this is enforced by the constructor and the various
@ -552,17 +862,17 @@ public final class AccessControlContext {
// to support the notion of a null PD and therefore this logic continues // to support the notion of a null PD and therefore this logic continues
// to support that notion. // to support that notion.
ProtectionDomain thisPd; ProtectionDomain thisPd;
for (int i = 0; i < context.length; i++) { for (int i = 0; i < thisContext.length; i++) {
match = false; match = false;
if ((thisPd = context[i]) == null) { if ((thisPd = thisContext[i]) == null) {
for (int j = 0; (j < that.context.length) && !match; j++) { for (int j = 0; (j < thatContext.length) && !match; j++) {
match = (that.context[j] == null); match = (thatContext[j] == null);
} }
} else { } else {
Class<?> thisPdClass = thisPd.getClass(); Class<?> thisPdClass = thisPd.getClass();
ProtectionDomain thatPd; ProtectionDomain thatPd;
for (int j = 0; (j < that.context.length) && !match; j++) { for (int j = 0; (j < thatContext.length) && !match; j++) {
thatPd = that.context[j]; thatPd = thatContext[j];
// Class check required to avoid PD exposure (4285406) // Class check required to avoid PD exposure (4285406)
match = (thatPd != null && match = (thatPd != null &&
@ -573,6 +883,29 @@ public final class AccessControlContext {
} }
return match; return match;
} }
private boolean containsAllLimits(AccessControlContext that) {
boolean match = false;
Permission thisPerm;
if (this.permissions == null && that.permissions == null)
return true;
for (int i = 0; i < this.permissions.length; i++) {
Permission limit = this.permissions[i];
Class <?> limitClass = limit.getClass();
match = false;
for (int j = 0; (j < that.permissions.length) && !match; j++) {
Permission perm = that.permissions[j];
match = (limitClass.equals(perm.getClass()) &&
limit.equals(perm));
}
if (!match) return false;
}
return match;
}
/** /**
* Returns the hash code value for this context. The hash code * Returns the hash code value for this context. The hash code
* is computed by exclusive or-ing the hash code of all the protection * is computed by exclusive or-ing the hash code of all the protection
@ -591,6 +924,7 @@ public final class AccessControlContext {
if (context[i] != null) if (context[i] != null)
hashCode ^= context[i].hashCode(); hashCode ^= context[i].hashCode();
} }
return hashCode; return hashCode;
} }
} }

View File

@ -82,9 +82,15 @@ import sun.reflect.Reflection;
* else if (caller i is marked as privileged) { * else if (caller i is marked as privileged) {
* if (a context was specified in the call to doPrivileged) * if (a context was specified in the call to doPrivileged)
* context.checkPermission(permission) * context.checkPermission(permission)
* return; * if (limited permissions were specified in the call to doPrivileged) {
* for (each limited permission) {
* if (the limited permission implies the requested permission)
* return;
* }
* } else
* return;
* } * }
* }; * }
* *
* // Next, check the context inherited when the thread was created. * // Next, check the context inherited when the thread was created.
* // Whenever a new thread is created, the AccessControlContext at * // Whenever a new thread is created, the AccessControlContext at
@ -101,11 +107,16 @@ import sun.reflect.Reflection;
* was marked as "privileged" via a <code>doPrivileged</code> * was marked as "privileged" via a <code>doPrivileged</code>
* call without a context argument (see below for information about a * call without a context argument (see below for information about a
* context argument). If that caller's domain has the * context argument). If that caller's domain has the
* specified permission, no further checking is done and * specified permission and at least one limiting permission argument (if any)
* implies the requested permission, no further checking is done and
* <code>checkPermission</code> * <code>checkPermission</code>
* returns quietly, indicating that the requested access is allowed. * returns quietly, indicating that the requested access is allowed.
* If that domain does not have the specified permission, an exception * If that domain does not have the specified permission, an exception
* is thrown, as usual. * is thrown, as usual. If the caller's domain had the specified permission
* but it was not implied by any limiting permission arguments given in the call
* to <code>doPrivileged</code> then the permission checking continues
* until there are no more callers or another <code>doPrivileged</code>
* call matches the requested permission and returns normally.
* *
* <p> The normal use of the "privileged" feature is as follows. If you * <p> The normal use of the "privileged" feature is as follows. If you
* don't need to return a value from within the "privileged" block, do * don't need to return a value from within the "privileged" block, do
@ -180,6 +191,9 @@ import sun.reflect.Reflection;
* *
* <p> Be *very* careful in your use of the "privileged" construct, and * <p> Be *very* careful in your use of the "privileged" construct, and
* always remember to make the privileged code section as small as possible. * always remember to make the privileged code section as small as possible.
* You can pass <code>Permission</code> arguments to further limit the
* scope of the "privilege" (see below).
*
* *
* <p> Note that <code>checkPermission</code> always performs security checks * <p> Note that <code>checkPermission</code> always performs security checks
* within the context of the currently executing thread. * within the context of the currently executing thread.
@ -215,7 +229,9 @@ import sun.reflect.Reflection;
* *
* <p> There are also times where you don't know a priori which permissions * <p> There are also times where you don't know a priori which permissions
* to check the context against. In these cases you can use the * to check the context against. In these cases you can use the
* doPrivileged method that takes a context: * doPrivileged method that takes a context. You can also limit the scope
* of the privileged code by passing additional <code>Permission</code>
* parameters.
* *
* <pre> {@code * <pre> {@code
* somemethod() { * somemethod() {
@ -223,12 +239,21 @@ import sun.reflect.Reflection;
* public Object run() { * public Object run() {
* // Code goes here. Any permission checks within this * // Code goes here. Any permission checks within this
* // run method will require that the intersection of the * // run method will require that the intersection of the
* // callers protection domain and the snapshot's * // caller's protection domain and the snapshot's
* // context have the desired permission. * // context have the desired permission. If a requested
* // permission is not implied by the limiting FilePermission
* // argument then checking of the thread continues beyond the
* // caller of doPrivileged.
* } * }
* }, acc); * }, acc, new FilePermission("/temp/*", read));
* ...normal code here... * ...normal code here...
* }}</pre> * }}</pre>
* <p> Passing a limiting <code>Permission</code> argument of an instance of
* <code>AllPermission</code> is equivalent to calling the equivalent
* <code>doPrivileged</code> method without limiting <code>Permission</code>
* arguments. Passing a zero length array of <code>Permission</code> disables
* the code privileges so that checking always continues beyond the caller of
* that <code>doPrivileged</code> method.
* *
* @see AccessControlContext * @see AccessControlContext
* *
@ -334,6 +359,112 @@ public final class AccessController {
public static native <T> T doPrivileged(PrivilegedAction<T> action, public static native <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context); AccessControlContext context);
/**
* Performs the specified <code>PrivilegedAction</code> with privileges
* enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited
* by specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null,
caller, parent, context, perms));
}
/**
* Performs the specified <code>PrivilegedAction</code> with privileges
* enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited
* by specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/** /**
* Performs the specified <code>PrivilegedExceptionAction</code> with * Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled. The action is performed with <i>all</i> of the * privileges enabled. The action is performed with <i>all</i> of the
@ -408,6 +539,22 @@ public final class AccessController {
private static AccessControlContext preserveCombiner(DomainCombiner combiner, private static AccessControlContext preserveCombiner(DomainCombiner combiner,
Class<?> caller) Class<?> caller)
{ {
return createWrapper(combiner, caller, null, null, null);
}
/**
* Create a wrapper to contain the limited privilege scope data.
*/
private static AccessControlContext
createWrapper(DomainCombiner combiner, Class<?> caller,
AccessControlContext parent, AccessControlContext context,
Permission[] perms)
{
return new AccessControlContext(getCallerPD(caller), combiner, parent,
context, perms);
}
private static ProtectionDomain getCallerPD(final Class <?> caller) {
ProtectionDomain callerPd = doPrivileged ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<ProtectionDomain>() { (new PrivilegedAction<ProtectionDomain>() {
public ProtectionDomain run() { public ProtectionDomain run() {
@ -415,18 +562,9 @@ public final class AccessController {
} }
}); });
// perform 'combine' on the caller of doPrivileged, return callerPd;
// even if the caller is from the bootclasspath
ProtectionDomain[] pds = new ProtectionDomain[] {callerPd};
if (combiner == null) {
return new AccessControlContext(pds);
} else {
return new AccessControlContext(combiner.combine(pds, null),
combiner);
}
} }
/** /**
* Performs the specified <code>PrivilegedExceptionAction</code> with * Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled and restricted by the specified * privileges enabled and restricted by the specified
@ -454,7 +592,7 @@ public final class AccessController {
* @exception NullPointerException if the action is <code>null</code> * @exception NullPointerException if the action is <code>null</code>
* *
* @see #doPrivileged(PrivilegedAction) * @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) * @see #doPrivileged(PrivilegedAction,AccessControlContext)
*/ */
@CallerSensitive @CallerSensitive
public static native <T> T public static native <T> T
@ -462,6 +600,118 @@ public final class AccessController {
AccessControlContext context) AccessControlContext context)
throws PrivilegedActionException; throws PrivilegedActionException;
/**
* Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited by
* specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws PrivilegedActionException if the specified action's
* <code>run</code> method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context, Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
}
/**
* Performs the specified <code>PrivilegedExceptionAction</code> with
* privileges enabled and restricted by the specified
* <code>AccessControlContext</code> and with a privilege scope limited by
* specified <code>Permission</code> arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* <code>AccessControlContext</code>.
* <p>
* If the action's <code>run</code> method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* <code>null</code>,
* then no additional restriction is applied.
* @param perms the <code>Permission</code> arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's <code>run</code> method.
*
* @throws PrivilegedActionException if the specified action's
* <code>run</code> method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is <code>null</code>
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
AccessControlContext context,
Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/** /**
* Returns the AccessControl context. i.e., it gets * Returns the AccessControl context. i.e., it gets
* the protection domains of all the callers on the stack, * the protection domains of all the callers on the stack,
@ -474,6 +724,7 @@ public final class AccessController {
private static native AccessControlContext getStackAccessControlContext(); private static native AccessControlContext getStackAccessControlContext();
/** /**
* Returns the "inherited" AccessControl context. This is the context * Returns the "inherited" AccessControl context. This is the context
* that existed when the thread was created. Package private so * that existed when the thread was created. Package private so
@ -484,9 +735,9 @@ public final class AccessController {
/** /**
* This method takes a "snapshot" of the current calling context, which * This method takes a "snapshot" of the current calling context, which
* includes the current Thread's inherited AccessControlContext, * includes the current Thread's inherited AccessControlContext and any
* and places it in an AccessControlContext object. This context may then * limited privilege scope, and places it in an AccessControlContext object.
* be checked at a later point, possibly in another thread. * This context may then be checked at a later point, possibly in another thread.
* *
* @see AccessControlContext * @see AccessControlContext
* *
@ -524,7 +775,7 @@ public final class AccessController {
*/ */
public static void checkPermission(Permission perm) public static void checkPermission(Permission perm)
throws AccessControlException throws AccessControlException
{ {
//System.err.println("checkPermission "+perm); //System.err.println("checkPermission "+perm);
//Thread.currentThread().dumpStack(); //Thread.currentThread().dumpStack();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 1999, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -112,10 +112,10 @@ public class DigestOutputStream extends FilterOutputStream {
* @see MessageDigest#update(byte) * @see MessageDigest#update(byte)
*/ */
public void write(int b) throws IOException { public void write(int b) throws IOException {
out.write(b);
if (on) { if (on) {
digest.update((byte)b); digest.update((byte)b);
} }
out.write(b);
} }
/** /**
@ -142,10 +142,10 @@ public class DigestOutputStream extends FilterOutputStream {
* @see MessageDigest#update(byte[], int, int) * @see MessageDigest#update(byte[], int, int)
*/ */
public void write(byte[] b, int off, int len) throws IOException { public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
if (on) { if (on) {
digest.update(b, off, len); digest.update(b, off, len);
} }
out.write(b, off, len);
} }
/** /**

File diff suppressed because it is too large Load Diff

View File

@ -180,13 +180,27 @@ public class Hashtable<K,V>
*/ */
static final long HASHSEED_OFFSET; static final long HASHSEED_OFFSET;
static final boolean USE_HASHSEED;
static { static {
try { String hashSeedProp = java.security.AccessController.doPrivileged(
UNSAFE = sun.misc.Unsafe.getUnsafe(); new sun.security.action.GetPropertyAction(
HASHSEED_OFFSET = UNSAFE.objectFieldOffset( "jdk.map.useRandomSeed"));
Hashtable.class.getDeclaredField("hashSeed")); boolean localBool = (null != hashSeedProp)
} catch (NoSuchFieldException | SecurityException e) { ? Boolean.parseBoolean(hashSeedProp) : false;
throw new InternalError("Failed to record hashSeed offset", e); USE_HASHSEED = localBool;
if (USE_HASHSEED) {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
Hashtable.class.getDeclaredField("hashSeed"));
} catch (NoSuchFieldException | SecurityException e) {
throw new InternalError("Failed to record hashSeed offset", e);
}
} else {
UNSAFE = null;
HASHSEED_OFFSET = 0;
} }
} }
} }
@ -194,21 +208,24 @@ public class Hashtable<K,V>
/** /**
* A randomizing value associated with this instance that is applied to * A randomizing value associated with this instance that is applied to
* hash code of keys to make hash collisions harder to find. * hash code of keys to make hash collisions harder to find.
*
* Non-final so it can be set lazily, but be sure not to set more than once.
*/ */
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this); transient final int hashSeed;
/**
* Return an initial value for the hashSeed, or 0 if the random seed is not
* enabled.
*/
final int initHashSeed() {
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
return sun.misc.Hashing.randomHashSeed(this);
}
return 0;
}
private int hash(Object k) { private int hash(Object k) {
if (k instanceof String) { return hashSeed ^ k.hashCode();
return ((String)k).hash32();
}
int h = hashSeed ^ k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
} }
/** /**
@ -232,6 +249,7 @@ public class Hashtable<K,V>
this.loadFactor = loadFactor; this.loadFactor = loadFactor;
table = new Entry<?,?>[initialCapacity]; table = new Entry<?,?>[initialCapacity];
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
hashSeed = initHashSeed();
} }
/** /**
@ -1187,8 +1205,10 @@ public class Hashtable<K,V>
s.defaultReadObject(); s.defaultReadObject();
// set hashMask // set hashMask
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET, if (Holder.USE_HASHSEED) {
sun.misc.Hashing.randomHashSeed(this)); Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
sun.misc.Hashing.randomHashSeed(this));
}
// Read the original length of the array and number of elements // Read the original length of the array and number of elements
int origlength = s.readInt(); int origlength = s.readInt();

View File

@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer {
*/ */
public String toString() { public String toString() {
return String.format( return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}", "%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(), this.getClass().getSimpleName(),
getCount(), getCount(),
getSum(), getSum(),

View File

@ -55,9 +55,9 @@ import java.io.*;
* order they were presented.) * order they were presented.)
* *
* <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is * <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
* provided to create a linked hash map whose order of iteration is the order * provided to create a <tt>LinkedHashMap</tt> whose order of iteration is the
* in which its entries were last accessed, from least-recently accessed to * order in which its entries were last accessed, from least-recently accessed
* most-recently (<i>access-order</i>). This kind of map is well-suited to * to most-recently (<i>access-order</i>). This kind of map is well-suited to
* building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method * building LRU caches. Invoking the <tt>put</tt> or <tt>get</tt> method
* results in an access to the corresponding entry (assuming it exists after * results in an access to the corresponding entry (assuming it exists after
* the invocation completes). The <tt>putAll</tt> method generates one entry * the invocation completes). The <tt>putAll</tt> method generates one entry
@ -242,23 +242,6 @@ public class LinkedHashMap<K,V>
header.before = header.after = header; header.before = header.after = header;
} }
/**
* Transfers all entries to new table array. This method is called
* by superclass resize. It is overridden for performance, as it is
* faster to iterate using our linked list.
*/
@Override
@SuppressWarnings("unchecked")
void transfer(HashMap.Entry[] newTable) {
int newCapacity = newTable.length;
for (Entry<K,V> e = header.after; e != header; e = e.after) {
int index = indexFor(e.hash, newCapacity);
e.next = (HashMap.Entry<K,V>)newTable[index];
newTable[index] = e;
}
}
/** /**
* Returns <tt>true</tt> if this map maps one or more keys to the * Returns <tt>true</tt> if this map maps one or more keys to the
* specified value. * specified value.
@ -320,7 +303,7 @@ public class LinkedHashMap<K,V>
// These fields comprise the doubly linked list used for iteration. // These fields comprise the doubly linked list used for iteration.
Entry<K,V> before, after; Entry<K,V> before, after;
Entry(int hash, K key, V value, HashMap.Entry<K,V> next) { Entry(int hash, K key, V value, Object next) {
super(hash, key, value, next); super(hash, key, value, next);
} }
@ -344,7 +327,7 @@ public class LinkedHashMap<K,V>
/** /**
* This method is invoked by the superclass whenever the value * This method is invoked by the superclass whenever the value
* of a pre-existing entry is read by Map.get or modified by Map.set. * of a pre-existing entry is read by Map.get or modified by Map.put.
* If the enclosing Map is access-ordered, it moves the entry * If the enclosing Map is access-ordered, it moves the entry
* to the end of the list; otherwise, it does nothing. * to the end of the list; otherwise, it does nothing.
*/ */
@ -422,8 +405,9 @@ public class LinkedHashMap<K,V>
* allocated entry to get inserted at the end of the linked list and * allocated entry to get inserted at the end of the linked list and
* removes the eldest entry if appropriate. * removes the eldest entry if appropriate.
*/ */
void addEntry(int hash, K key, V value, int bucketIndex) { @Override
super.addEntry(hash, key, value, bucketIndex); void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) {
super.addEntry(hash, key, value, bucketIndex, checkIfNeedTree);
// Remove eldest entry if instructed // Remove eldest entry if instructed
Entry<K,V> eldest = header.after; Entry<K,V> eldest = header.after;
@ -432,17 +416,14 @@ public class LinkedHashMap<K,V>
} }
} }
/** /*
* This override differs from addEntry in that it doesn't resize the * Create a new LinkedHashMap.Entry and setup the before/after pointers
* table or remove the eldest entry.
*/ */
void createEntry(int hash, K key, V value, int bucketIndex) { @Override
@SuppressWarnings("unchecked") HashMap.Entry<K,V> newEntry(int hash, K key, V value, Object next) {
HashMap.Entry<K,V> old = (HashMap.Entry<K,V>)table[bucketIndex]; Entry<K,V> newEntry = new Entry<>(hash, key, value, next);
Entry<K,V> e = new Entry<>(hash, key, value, old); newEntry.addBefore(header);
table[bucketIndex] = e; return newEntry;
e.addBefore(header);
size++;
} }
/** /**

View File

@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
*/ */
public String toString() { public String toString() {
return String.format( return String.format(
"%s{count=%d, sum=%d, min=%d, average=%d, max=%d}", "%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(), this.getClass().getSimpleName(),
getCount(), getCount(),
getSum(), getSum(),

View File

@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(IntConsumer action) { default void forEachRemaining(IntConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextInt()); action.accept(nextInt());
} }
@ -123,6 +124,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((IntConsumer) action); forEachRemaining((IntConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
forEachRemaining((IntConsumer) action::accept); forEachRemaining((IntConsumer) action::accept);
@ -162,6 +165,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(LongConsumer action) { default void forEachRemaining(LongConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextLong()); action.accept(nextLong());
} }
@ -194,6 +198,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((LongConsumer) action); forEachRemaining((LongConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
forEachRemaining((LongConsumer) action::accept); forEachRemaining((LongConsumer) action::accept);
@ -232,6 +238,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
* @throws NullPointerException if the specified action is null * @throws NullPointerException if the specified action is null
*/ */
default void forEachRemaining(DoubleConsumer action) { default void forEachRemaining(DoubleConsumer action) {
Objects.requireNonNull(action);
while (hasNext()) while (hasNext())
action.accept(nextDouble()); action.accept(nextDouble());
} }
@ -265,6 +272,8 @@ public interface PrimitiveIterator<T> extends Iterator<T> {
forEachRemaining((DoubleConsumer) action); forEachRemaining((DoubleConsumer) action);
} }
else { else {
// The method reference action::accept is never null
Objects.requireNonNull(action);
if (Tripwire.ENABLED) if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)"); Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
forEachRemaining((DoubleConsumer) action::accept); forEachRemaining((DoubleConsumer) action::accept);

View File

@ -394,9 +394,9 @@ public interface Spliterator<T> {
* Convenience method that returns {@link #estimateSize()} if this * Convenience method that returns {@link #estimateSize()} if this
* Spliterator is {@link #SIZED}, else {@code -1}. * Spliterator is {@link #SIZED}, else {@code -1}.
* @implSpec * @implSpec
* The default returns the result of {@code estimateSize()} if the * The default implementation returns the result of {@code estimateSize()}
* Spliterator reports a characteristic of {@code SIZED}, and {@code -1} * if the Spliterator reports a characteristic of {@code SIZED}, and
* otherwise. * {@code -1} otherwise.
* *
* @return the exact size, if known, else {@code -1}. * @return the exact size, if known, else {@code -1}.
*/ */

View File

@ -29,14 +29,6 @@ package java.util;
* by a delimiter and optionally starting with a supplied prefix * by a delimiter and optionally starting with a supplied prefix
* and ending with a supplied suffix. * and ending with a supplied suffix.
* <p> * <p>
* For example, the String {@code "[George:Sally:Fred]"} may
* be constructed as follows:
* <pre> {@code
* StringJoiner sj = new StringJoiner(":", "[", "]");
* sj.add("George").add("Sally").add("Fred");
* String desiredString = sj.toString();
* }</pre>
* <p>
* Prior to adding something to the {@code StringJoiner}, its * Prior to adding something to the {@code StringJoiner}, its
* {@code sj.toString()} method will, by default, return {@code prefix + suffix}. * {@code sj.toString()} method will, by default, return {@code prefix + suffix}.
* However, if the {@code setEmptyValue} method is called, the {@code emptyValue} * However, if the {@code setEmptyValue} method is called, the {@code emptyValue}
@ -45,17 +37,28 @@ package java.util;
* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the * <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the
* {@code suffix} is <code>"}"</code> and nothing has been added to the * {@code suffix} is <code>"}"</code> and nothing has been added to the
* {@code StringJoiner}. * {@code StringJoiner}.
* <p> *
* A {@code StringJoiner} may be employed to create formatted output from a * @apiNote
* collection using lambda expressions as shown in the following example. * <p>The String {@code "[George:Sally:Fred]"} may be constructed as follows:
* *
* <pre> {@code * <pre> {@code
* List<Person> people = ... * StringJoiner sj = new StringJoiner(":", "[", "]");
* String commaSeparatedNames = * sj.add("George").add("Sally").add("Fred");
* people.map(p -> p.getName()).into(new StringJoiner(", ")).toString(); * String desiredString = sj.toString();
* }</pre>
* <p>
* A {@code StringJoiner} may be employed to create formatted output from a
* {@link java.util.stream.Stream} using
* {@link java.util.stream.Collectors#toStringJoiner}. For example:
*
* <pre> {@code
* List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
* String commaSeparatedNumbers = numbers.stream()
* .map(i -> i.toString())
* .collect(Collectors.toStringJoiner(", ")).toString();
* }</pre> * }</pre>
* *
* @author Jim Gish * @see java.util.stream.Collectors#toStringJoiner
* @since 1.8 * @since 1.8
*/ */
public final class StringJoiner { public final class StringJoiner {

View File

@ -187,11 +187,37 @@ public class WeakHashMap<K,V>
*/ */
int modCount; int modCount;
private static class Holder {
static final boolean USE_HASHSEED;
static {
String hashSeedProp = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"jdk.map.useRandomSeed"));
boolean localBool = (null != hashSeedProp)
? Boolean.parseBoolean(hashSeedProp) : false;
USE_HASHSEED = localBool;
}
}
/** /**
* A randomizing value associated with this instance that is applied to * A randomizing value associated with this instance that is applied to
* hash code of keys to make hash collisions harder to find. * hash code of keys to make hash collisions harder to find.
*
* Non-final so it can be set lazily, but be sure not to set more than once.
*/ */
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this); transient int hashSeed;
/**
* Initialize the hashing mask value.
*/
final void initHashSeed() {
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
// Do not set hashSeed more than once!
// assert hashSeed == 0;
hashSeed = sun.misc.Hashing.randomHashSeed(this);
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Entry<K,V>[] newTable(int n) { private Entry<K,V>[] newTable(int n) {
@ -223,6 +249,7 @@ public class WeakHashMap<K,V>
table = newTable(capacity); table = newTable(capacity);
this.loadFactor = loadFactor; this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor); threshold = (int)(capacity * loadFactor);
initHashSeed();
} }
/** /**
@ -298,10 +325,7 @@ public class WeakHashMap<K,V>
* in lower bits. * in lower bits.
*/ */
final int hash(Object k) { final int hash(Object k) {
if (k instanceof String) { int h = hashSeed ^ k.hashCode();
return ((String) k).hash32();
}
int h = hashSeed ^ k.hashCode();
// This function ensures that hashCodes that differ only by // This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded // constant multiples at each bit position have a bounded
@ -1076,9 +1100,10 @@ public class WeakHashMap<K,V>
} }
else else
mc = expectedModCount; mc = expectedModCount;
if (tab.length >= hi && (i = index) >= 0 && i < hi) { if (tab.length >= hi && (i = index) >= 0 &&
index = hi; (i < (index = hi) || current != null)) {
WeakHashMap.Entry<K,V> p = current; WeakHashMap.Entry<K,V> p = current;
current = null; // exhaust
do { do {
if (p == null) if (p == null)
p = tab[i++]; p = tab[i++];
@ -1155,9 +1180,10 @@ public class WeakHashMap<K,V>
} }
else else
mc = expectedModCount; mc = expectedModCount;
if (tab.length >= hi && (i = index) >= 0 && i < hi) { if (tab.length >= hi && (i = index) >= 0 &&
index = hi; (i < (index = hi) || current != null)) {
WeakHashMap.Entry<K,V> p = current; WeakHashMap.Entry<K,V> p = current;
current = null; // exhaust
do { do {
if (p == null) if (p == null)
p = tab[i++]; p = tab[i++];
@ -1232,9 +1258,10 @@ public class WeakHashMap<K,V>
} }
else else
mc = expectedModCount; mc = expectedModCount;
if (tab.length >= hi && (i = index) >= 0 && i < hi) { if (tab.length >= hi && (i = index) >= 0 &&
index = hi; (i < (index = hi) || current != null)) {
WeakHashMap.Entry<K,V> p = current; WeakHashMap.Entry<K,V> p = current;
current = null; // exhaust
do { do {
if (p == null) if (p == null)
p = tab[i++]; p = tab[i++];

View File

@ -128,6 +128,14 @@ import java.util.Locale;
* installed SPI providers, and "JRE" represents the locale sensitive services * installed SPI providers, and "JRE" represents the locale sensitive services
* in the Java Runtime Environment, the locale sensitive services in the SPI * in the Java Runtime Environment, the locale sensitive services in the SPI
* providers are looked up first. * providers are looked up first.
* <p>
* There are two other possible locale sensitive service providers, i.e., "CLDR"
* which is a provider based on Unicode Consortium's
* <a href="http://cldr.unicode.org/">CLDR Project</a>, and "HOST" which is a
* provider that reflects the user's custom settings in the underlying operating
* system. These two providers may not be available, depending on the Java Runtime
* Environment implementation. Specifying "JRE,SPI" is identical to the default
* behavior, which is compatibile with the prior releases.
* *
* @since 1.6 * @since 1.6
*/ */

View File

@ -603,7 +603,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
/** /**
* Returns an {@link OptionalDouble} describing the first element of this * Returns an {@link OptionalDouble} describing the first element of this
* stream (in the encounter order), or an empty {@code OptionalDouble} if * stream (in the encounter order), or an empty {@code OptionalDouble} if
* the stream is empty. If the stream has no encounter order, than any * the stream is empty. If the stream has no encounter order, then any
* element may be returned. * element may be returned.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting

View File

@ -588,7 +588,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
/** /**
* Returns an {@link OptionalInt} describing the first element of this * Returns an {@link OptionalInt} describing the first element of this
* stream (in the encounter order), or an empty {@code OptionalInt} if the * stream (in the encounter order), or an empty {@code OptionalInt} if the
* stream is empty. If the stream has no encounter order, than any element * stream is empty. If the stream has no encounter order, then any element
* may be returned. * may be returned.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting

View File

@ -588,7 +588,7 @@ public interface LongStream extends BaseStream<Long, LongStream> {
/** /**
* Returns an {@link OptionalLong} describing the first element of this * Returns an {@link OptionalLong} describing the first element of this
* stream (in the encounter order), or an empty {@code OptionalLong} if the * stream (in the encounter order), or an empty {@code OptionalLong} if the
* stream is empty. If the stream has no encounter order, than any element * stream is empty. If the stream has no encounter order, then any element
* may be returned. * may be returned.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting

View File

@ -754,7 +754,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
/** /**
* Returns an {@link Optional} describing the first element of this stream * Returns an {@link Optional} describing the first element of this stream
* (in the encounter order), or an empty {@code Optional} if the stream is * (in the encounter order), or an empty {@code Optional} if the stream is
* empty. If the stream has no encounter order, than any element may be * empty. If the stream has no encounter order, then any element may be
* returned. * returned.
* *
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting

View File

@ -38,7 +38,7 @@ import java.util.function.LongConsumer;
* <p>A {@code StreamBuilder} has a lifecycle, where it starts in a building * <p>A {@code StreamBuilder} has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a built * phase, during which elements can be added, and then transitions to a built
* phase, after which elements may not be added. The built phase begins * phase, after which elements may not be added. The built phase begins
* when the {@link #build()}} method is called, which creates an ordered * when the {@link #build()} method is called, which creates an ordered
* {@code Stream} whose elements are the elements that were added to the stream * {@code Stream} whose elements are the elements that were added to the stream
* builder, in the order they were added. * builder, in the order they were added.
* *
@ -98,7 +98,7 @@ public interface StreamBuilder<T> extends Consumer<T> {
* <p>A stream builder has a lifecycle, where it starts in a building * <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a * phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase * built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an * begins when the {@link #build()} method is called, which creates an
* ordered stream whose elements are the elements that were added to the * ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added. * stream builder, in the order they were added.
* *
@ -155,7 +155,7 @@ public interface StreamBuilder<T> extends Consumer<T> {
* <p>A stream builder has a lifecycle, where it starts in a building * <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a * phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase * built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an * begins when the {@link #build()} method is called, which creates an
* ordered stream whose elements are the elements that were added to the * ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added. * stream builder, in the order they were added.
* *
@ -209,6 +209,13 @@ public interface StreamBuilder<T> extends Consumer<T> {
/** /**
* A mutable builder for a {@code DoubleStream}. * A mutable builder for a {@code DoubleStream}.
* *
* <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase
* begins when the {@link #build()} method is called, which creates an
* ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added.
*
* @see LongStream#builder() * @see LongStream#builder()
* @since 1.8 * @since 1.8
*/ */
@ -217,13 +224,6 @@ public interface StreamBuilder<T> extends Consumer<T> {
/** /**
* Adds an element to the stream being built. * Adds an element to the stream being built.
* *
* <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an
* ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added.
*
* @throws IllegalStateException if the builder has already transitioned * @throws IllegalStateException if the builder has already transitioned
* to the built state * to the built state
*/ */

View File

@ -41,7 +41,11 @@ import java.util.function.Supplier;
* *
* @since 1.8 * @since 1.8
*/ */
public class StreamSupport { public final class StreamSupport {
// Suppresses default constructor, ensuring non-instantiability.
private StreamSupport() {}
/** /**
* Creates a new sequential {@code Stream} from a {@code Spliterator}. * Creates a new sequential {@code Stream} from a {@code Spliterator}.
* *
@ -50,7 +54,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -75,7 +79,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -102,7 +106,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #stream(java.util.Spliterator)} instead. * more efficient to use {@link #stream(java.util.Spliterator)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -138,7 +142,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #stream(Spliterator)} instead. * more efficient to use {@link #stream(Spliterator)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -172,7 +176,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)}} should be used to * {@link #stream(Supplier, int)}} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -195,7 +199,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)}} should be used to * {@link #stream(Supplier, int)}} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -220,7 +224,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead. * more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -254,7 +258,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #intStream(Spliterator.OfInt)} instead. * more efficient to use {@link #intStream(Spliterator.OfInt)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -286,7 +290,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -310,7 +314,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -335,7 +339,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead. * more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -369,7 +373,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #longStream(Spliterator.OfLong)} instead. * more efficient to use {@link #longStream(Spliterator.OfLong)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -402,7 +406,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -426,7 +430,7 @@ public class StreamSupport {
* *
* <p>It is strongly recommended the spliterator report a characteristic of * <p>It is strongly recommended the spliterator report a characteristic of
* {@code IMMUTABLE} or {@code CONCURRENT}, or be * {@code IMMUTABLE} or {@code CONCURRENT}, or be
* <a href="Spliterator.html#binding">late-binding</a>. Otherwise, * <a href="../Spliterator.html#binding">late-binding</a>. Otherwise,
* {@link #stream(Supplier, int)} should be used to * {@link #stream(Supplier, int)} should be used to
* reduce the scope of potential interference with the source. See * reduce the scope of potential interference with the source. See
* <a href="package-summary.html#Non-Interference">Non-Interference</a> for * <a href="package-summary.html#Non-Interference">Non-Interference</a> for
@ -451,7 +455,7 @@ public class StreamSupport {
* <p> * <p>
* For spliterators that report a characteristic of {@code IMMUTABLE} * For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead. * more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the
@ -485,7 +489,7 @@ public class StreamSupport {
* *
* <p>For spliterators that report a characteristic of {@code IMMUTABLE} * <p>For spliterators that report a characteristic of {@code IMMUTABLE}
* or {@code CONCURRENT}, or that are * or {@code CONCURRENT}, or that are
* <a href="Spliterator.html#binding">late-binding</a>, it is likely * <a href="../Spliterator.html#binding">late-binding</a>, it is likely
* more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead. * more efficient to use {@link #doubleStream(Spliterator.OfDouble)} instead.
* The use of a {@code Supplier} in this form provides a level of * The use of a {@code Supplier} in this form provides a level of
* indirection that reduces the scope of potential interference with the * indirection that reduces the scope of potential interference with the

View File

@ -68,6 +68,14 @@ interface ZipConstants {
static final int EXTSIZ = 8; // compressed size static final int EXTSIZ = 8; // compressed size
static final int EXTLEN = 12; // uncompressed size static final int EXTLEN = 12; // uncompressed size
/*
* Extra field header ID
*/
static final int EXTID_ZIP64 = 0x0001; // Zip64
static final int EXTID_NTFS = 0x000a; // NTFS
static final int EXTID_UNIX = 0x000d; // UNIX
static final int EXTID_EXTT = 0x5455; // Info-ZIP Extended Timestamp
/* /*
* Central directory (CEN) header field offsets * Central directory (CEN) header field offsets
*/ */

View File

@ -25,8 +25,6 @@
package java.util.zip; package java.util.zip;
import java.util.Date;
/** /**
* This class is used to represent a ZIP file entry. * This class is used to represent a ZIP file entry.
* *
@ -35,7 +33,7 @@ import java.util.Date;
public public
class ZipEntry implements ZipConstants, Cloneable { class ZipEntry implements ZipConstants, Cloneable {
String name; // entry name String name; // entry name
long time = -1; // modification time (in DOS time) long mtime = -1; // last modification time
long crc = -1; // crc-32 of entry data long crc = -1; // crc-32 of entry data
long size = -1; // uncompressed size of entry data long size = -1; // uncompressed size of entry data
long csize = -1; // compressed size of entry data long csize = -1; // compressed size of entry data
@ -79,7 +77,7 @@ class ZipEntry implements ZipConstants, Cloneable {
*/ */
public ZipEntry(ZipEntry e) { public ZipEntry(ZipEntry e) {
name = e.name; name = e.name;
time = e.time; mtime = e.mtime;
crc = e.crc; crc = e.crc;
size = e.size; size = e.size;
csize = e.csize; csize = e.csize;
@ -89,7 +87,7 @@ class ZipEntry implements ZipConstants, Cloneable {
comment = e.comment; comment = e.comment;
} }
/* /**
* Creates a new un-initialized zip entry * Creates a new un-initialized zip entry
*/ */
ZipEntry() {} ZipEntry() {}
@ -103,22 +101,26 @@ class ZipEntry implements ZipConstants, Cloneable {
} }
/** /**
* Sets the modification time of the entry. * Sets the last modification time of the entry.
* @param time the entry modification time in number of milliseconds *
* since the epoch * @param time the last modification time of the entry in milliseconds since the epoch
* @see #getTime() * @see #getTime()
*/ */
public void setTime(long time) { public void setTime(long time) {
this.time = javaToDosTime(time); this.mtime = time;
} }
/** /**
* Returns the modification time of the entry, or -1 if not specified. * Returns the last modification time of the entry.
* @return the modification time of the entry, or -1 if not specified * <p> The last modificatin time may come from zip entry's extensible
* data field {@code NTFS} or {@code Info-ZIP Extended Timestamp}, if
* the entry is read from {@link ZipInputStream} or {@link ZipFile}.
*
* @return the last modification time of the entry, or -1 if not specified
* @see #setTime(long) * @see #setTime(long)
*/ */
public long getTime() { public long getTime() {
return time != -1 ? dosToJavaTime(time) : -1; return mtime;
} }
/** /**
@ -277,35 +279,6 @@ class ZipEntry implements ZipConstants, Cloneable {
return getName(); return getName();
} }
/*
* Converts DOS time to Java time (number of milliseconds since epoch).
*/
private static long dosToJavaTime(long dtime) {
@SuppressWarnings("deprecation") // Use of date constructor.
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
(int)(((dtime >> 21) & 0x0f) - 1),
(int)((dtime >> 16) & 0x1f),
(int)((dtime >> 11) & 0x1f),
(int)((dtime >> 5) & 0x3f),
(int)((dtime << 1) & 0x3e));
return d.getTime();
}
/*
* Converts Java time to DOS time.
*/
@SuppressWarnings("deprecation") // Use of date methods
private static long javaToDosTime(long time) {
Date d = new Date(time);
int year = d.getYear() + 1900;
if (year < 1980) {
return (1 << 21) | (1 << 16);
}
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
d.getSeconds() >> 1;
}
/** /**
* Returns the hash code value for this entry. * Returns the hash code value for this entry.
*/ */

View File

@ -46,6 +46,7 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipConstants64.*;
import static java.util.zip.ZipUtils.*;
/** /**
* This class is used to read entries from a zip file. * This class is used to read entries from a zip file.
@ -564,12 +565,44 @@ class ZipFile implements ZipConstants, Closeable {
e.name = zc.toString(bname, bname.length); e.name = zc.toString(bname, bname.length);
} }
} }
e.time = getEntryTime(jzentry);
e.crc = getEntryCrc(jzentry); e.crc = getEntryCrc(jzentry);
e.size = getEntrySize(jzentry); e.size = getEntrySize(jzentry);
e. csize = getEntryCSize(jzentry); e. csize = getEntryCSize(jzentry);
e.method = getEntryMethod(jzentry); e.method = getEntryMethod(jzentry);
e.extra = getEntryBytes(jzentry, JZENTRY_EXTRA); e.extra = getEntryBytes(jzentry, JZENTRY_EXTRA);
if (e.extra != null) {
byte[] extra = e.extra;
int len = e.extra.length;
int off = 0;
while (off + 4 < len) {
int pos = off;
int tag = get16(extra, pos);
int sz = get16(extra, pos + 2);
pos += 4;
if (pos + sz > len) // invalid data
break;
switch (tag) {
case EXTID_NTFS:
pos += 4; // reserved 4 bytes
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
break;
e.mtime = winToJavaTime(get64(extra, pos + 4));
break;
case EXTID_EXTT:
int flag = Byte.toUnsignedInt(extra[pos++]);
if ((flag & 0x1) != 0) {
e.mtime = unixToJavaTime(get32(extra, pos));
pos += 4;
}
break;
default: // unknown tag
}
off += (sz + 4);
}
}
if (e.mtime == -1) {
e.mtime = dosToJavaTime(getEntryTime(jzentry));
}
byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT); byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
if (bcomm == null) { if (bcomm == null) {
e.comment = null; e.comment = null;

View File

@ -32,6 +32,7 @@ import java.io.PushbackInputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipConstants64.*;
import static java.util.zip.ZipUtils.*;
/** /**
* This class implements an input stream filter for reading files in the * This class implements an input stream filter for reading files in the
@ -302,7 +303,7 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
throw new ZipException("encrypted ZIP entry not supported"); throw new ZipException("encrypted ZIP entry not supported");
} }
e.method = get16(tmpbuf, LOCHOW); e.method = get16(tmpbuf, LOCHOW);
e.time = get32(tmpbuf, LOCTIM); e.mtime = dosToJavaTime(get32(tmpbuf, LOCTIM));
if ((flag & 8) == 8) { if ((flag & 8) == 8) {
/* "Data Descriptor" present */ /* "Data Descriptor" present */
if (e.method != DEFLATED) { if (e.method != DEFLATED) {
@ -316,32 +317,51 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
} }
len = get16(tmpbuf, LOCEXT); len = get16(tmpbuf, LOCEXT);
if (len > 0) { if (len > 0) {
byte[] bb = new byte[len]; byte[] extra = new byte[len];
readFully(bb, 0, len); readFully(extra, 0, len);
e.setExtra(bb); e.setExtra(extra);
// extra fields are in "HeaderID(2)DataSize(2)Data... format // extra fields are in "HeaderID(2)DataSize(2)Data... format
if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) { int off = 0;
int off = 0; while (off + 4 < len) {
while (off + 4 < len) { int pos = off;
int sz = get16(bb, off + 2); int tag = get16(extra, pos);
if (get16(bb, off) == ZIP64_EXTID) { int sz = get16(extra, pos + 2);
off += 4; pos += 4;
// LOC extra zip64 entry MUST include BOTH original and if (pos + sz > len) // invalid data
// compressed file size fields break;
if (sz < 16 || (off + sz) > len ) { switch (tag) {
// Invalid zip64 extra fields, simply skip. Even it's case EXTID_ZIP64 :
// rare, it's possible the entry size happens to be // LOC extra zip64 entry MUST include BOTH original and
// the magic value and it "accidnetly" has some bytes // compressed file size fields.
// in extra match the id. //
return e; // If invalid zip64 extra fields, simply skip. Even it's
} // rare, it's possible the entry size happens to be
e.size = get64(bb, off); // the magic value and it "accidently" has some bytes
e.csize = get64(bb, off + 8); // in extra match the id.
break; if (sz >= 16 && (pos + sz) <= len ) {
e.size = get64(extra, pos);
e.csize = get64(extra, pos + 8);
} }
off += (sz + 4); break;
case EXTID_NTFS:
pos += 4; // reserved 4 bytes
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
break;
// override the loc field, NTFS time has 'microsecond' granularity
e.mtime = winToJavaTime(get64(extra, pos + 4));
break;
case EXTID_EXTT:
int flag = Byte.toUnsignedInt(extra[pos++]);
if ((flag & 0x1) != 0) {
e.mtime = unixToJavaTime(get32(extra, pos));
pos += 4;
}
break;
default: // unknown tag
} }
off += (sz + 4);
} }
} }
return e; return e;
} }
@ -430,27 +450,4 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
} }
} }
/*
* Fetches unsigned 16-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final int get16(byte b[], int off) {
return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
}
/*
* Fetches unsigned 32-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final long get32(byte b[], int off) {
return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
}
/*
* Fetches signed 64-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final long get64(byte b[], int off) {
return get32(b, off) | (get32(b, off+4) << 32);
}
} }

View File

@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Vector; import java.util.Vector;
import java.util.HashSet; import java.util.HashSet;
import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipConstants64.*;
import static java.util.zip.ZipUtils.*;
/** /**
* This class implements an output stream filter for writing files in the * This class implements an output stream filter for writing files in the
@ -190,7 +191,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
if (current != null) { if (current != null) {
closeEntry(); // close previous entry closeEntry(); // close previous entry
} }
if (e.time == -1) { if (e.mtime == -1) {
e.setTime(System.currentTimeMillis()); e.setTime(System.currentTimeMillis());
} }
if (e.method == -1) { if (e.method == -1) {
@ -382,16 +383,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
private void writeLOC(XEntry xentry) throws IOException { private void writeLOC(XEntry xentry) throws IOException {
ZipEntry e = xentry.entry; ZipEntry e = xentry.entry;
int flag = e.flag; int flag = e.flag;
int elen = (e.extra != null) ? e.extra.length : 0;
boolean hasZip64 = false; boolean hasZip64 = false;
int elen = (e.extra != null) ? e.extra.length : 0;
int eoff = 0;
boolean foundEXTT = false; // if EXTT already present
// do nothing.
while (eoff + 4 < elen) {
int tag = get16(e.extra, eoff);
int sz = get16(e.extra, eoff + 2);
if (tag == EXTID_EXTT) {
foundEXTT = true;
}
eoff += (4 + sz);
}
writeInt(LOCSIG); // LOC header signature writeInt(LOCSIG); // LOC header signature
if ((flag & 8) == 8) { if ((flag & 8) == 8) {
writeShort(version(e)); // version needed to extract writeShort(version(e)); // version needed to extract
writeShort(flag); // general purpose bit flag writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method writeShort(e.method); // compression method
writeInt(e.time); // last modification time writeInt(javaToDosTime(e.mtime)); // last modification time
// store size, uncompressed size, and crc-32 in data descriptor // store size, uncompressed size, and crc-32 in data descriptor
// immediately following compressed entry data // immediately following compressed entry data
@ -407,7 +417,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
} }
writeShort(flag); // general purpose bit flag writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method writeShort(e.method); // compression method
writeInt(e.time); // last modification time writeInt(javaToDosTime(e.mtime)); // last modification time
writeInt(e.crc); // crc-32 writeInt(e.crc); // crc-32
if (hasZip64) { if (hasZip64) {
writeInt(ZIP64_MAGICVAL); writeInt(ZIP64_MAGICVAL);
@ -420,6 +430,8 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
} }
byte[] nameBytes = zc.getBytes(e.name); byte[] nameBytes = zc.getBytes(e.name);
writeShort(nameBytes.length); writeShort(nameBytes.length);
if (!foundEXTT)
elen += 9; // use Info-ZIP's ext time in extra
writeShort(elen); writeShort(elen);
writeBytes(nameBytes, 0, nameBytes.length); writeBytes(nameBytes, 0, nameBytes.length);
if (hasZip64) { if (hasZip64) {
@ -428,6 +440,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
writeLong(e.size); writeLong(e.size);
writeLong(e.csize); writeLong(e.csize);
} }
if (!foundEXTT) {
writeShort(EXTID_EXTT);
writeShort(5); // size for the folowing data block
writeByte(0x1); // flags byte, mtime only
writeInt(javaToUnixTime(e.mtime));
}
if (e.extra != null) { if (e.extra != null) {
writeBytes(e.extra, 0, e.extra.length); writeBytes(e.extra, 0, e.extra.length);
} }
@ -457,25 +475,25 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
ZipEntry e = xentry.entry; ZipEntry e = xentry.entry;
int flag = e.flag; int flag = e.flag;
int version = version(e); int version = version(e);
long csize = e.csize; long csize = e.csize;
long size = e.size; long size = e.size;
long offset = xentry.offset; long offset = xentry.offset;
int e64len = 0; int elenZIP64 = 0;
boolean hasZip64 = false; boolean hasZip64 = false;
if (e.csize >= ZIP64_MAGICVAL) { if (e.csize >= ZIP64_MAGICVAL) {
csize = ZIP64_MAGICVAL; csize = ZIP64_MAGICVAL;
e64len += 8; // csize(8) elenZIP64 += 8; // csize(8)
hasZip64 = true; hasZip64 = true;
} }
if (e.size >= ZIP64_MAGICVAL) { if (e.size >= ZIP64_MAGICVAL) {
size = ZIP64_MAGICVAL; // size(8) size = ZIP64_MAGICVAL; // size(8)
e64len += 8; elenZIP64 += 8;
hasZip64 = true; hasZip64 = true;
} }
if (xentry.offset >= ZIP64_MAGICVAL) { if (xentry.offset >= ZIP64_MAGICVAL) {
offset = ZIP64_MAGICVAL; offset = ZIP64_MAGICVAL;
e64len += 8; // offset(8) elenZIP64 += 8; // offset(8)
hasZip64 = true; hasZip64 = true;
} }
writeInt(CENSIG); // CEN header signature writeInt(CENSIG); // CEN header signature
@ -488,18 +506,32 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
} }
writeShort(flag); // general purpose bit flag writeShort(flag); // general purpose bit flag
writeShort(e.method); // compression method writeShort(e.method); // compression method
writeInt(e.time); // last modification time writeInt(javaToDosTime(e.mtime)); // last modification time
writeInt(e.crc); // crc-32 writeInt(e.crc); // crc-32
writeInt(csize); // compressed size writeInt(csize); // compressed size
writeInt(size); // uncompressed size writeInt(size); // uncompressed size
byte[] nameBytes = zc.getBytes(e.name); byte[] nameBytes = zc.getBytes(e.name);
writeShort(nameBytes.length); writeShort(nameBytes.length);
int elen = (e.extra != null) ? e.extra.length : 0;
int eoff = 0;
boolean foundEXTT = false; // if EXTT already present
// do nothing.
while (eoff + 4 < elen) {
int tag = get16(e.extra, eoff);
int sz = get16(e.extra, eoff + 2);
if (tag == EXTID_EXTT) {
foundEXTT = true;
}
eoff += (4 + sz);
}
if (hasZip64) { if (hasZip64) {
// + headid(2) + datasize(2) // + headid(2) + datasize(2)
writeShort(e64len + 4 + (e.extra != null ? e.extra.length : 0)); elen += (elenZIP64 + 4);
} else {
writeShort(e.extra != null ? e.extra.length : 0);
} }
if (!foundEXTT)
elen += 9; // Info-ZIP's Extended Timestamp
writeShort(elen);
byte[] commentBytes; byte[] commentBytes;
if (e.comment != null) { if (e.comment != null) {
commentBytes = zc.getBytes(e.comment); commentBytes = zc.getBytes(e.comment);
@ -515,7 +547,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
writeBytes(nameBytes, 0, nameBytes.length); writeBytes(nameBytes, 0, nameBytes.length);
if (hasZip64) { if (hasZip64) {
writeShort(ZIP64_EXTID);// Zip64 extra writeShort(ZIP64_EXTID);// Zip64 extra
writeShort(e64len); writeShort(elenZIP64);
if (size == ZIP64_MAGICVAL) if (size == ZIP64_MAGICVAL)
writeLong(e.size); writeLong(e.size);
if (csize == ZIP64_MAGICVAL) if (csize == ZIP64_MAGICVAL)
@ -523,6 +555,12 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
if (offset == ZIP64_MAGICVAL) if (offset == ZIP64_MAGICVAL)
writeLong(xentry.offset); writeLong(xentry.offset);
} }
if (!foundEXTT) {
writeShort(EXTID_EXTT);
writeShort(5);
writeByte(0x1); // flags byte
writeInt(javaToUnixTime(e.mtime));
}
if (e.extra != null) { if (e.extra != null) {
writeBytes(e.extra, 0, e.extra.length); writeBytes(e.extra, 0, e.extra.length);
} }
@ -588,6 +626,15 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
} }
} }
/*
* Writes a 8-bit byte to the output stream.
*/
private void writeByte(int v) throws IOException {
OutputStream out = this.out;
out.write(v & 0xff);
written += 1;
}
/* /*
* Writes a 16-bit short to the output stream in little-endian byte order. * Writes a 16-bit short to the output stream in little-endian byte order.
*/ */

View File

@ -0,0 +1,120 @@
/*
* 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.zip;
import java.util.Date;
import java.util.concurrent.TimeUnit;
class ZipUtils {
// used to adjust values between Windows and java epoch
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
/**
* Converts Windows time (in microseconds, UTC/GMT) time to Java time.
*/
public static final long winToJavaTime(long wtime) {
return TimeUnit.MILLISECONDS.convert(
wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, TimeUnit.MICROSECONDS);
}
/**
* Converts Java time to Windows time.
*/
public static final long javaToWinTime(long time) {
return (TimeUnit.MICROSECONDS.convert(time, TimeUnit.MILLISECONDS)
- WINDOWS_EPOCH_IN_MICROSECONDS) * 10;
}
/**
* Converts "standard Unix time"(in seconds, UTC/GMT) to Java time
*/
public static final long unixToJavaTime(long utime) {
return TimeUnit.MILLISECONDS.convert(utime, TimeUnit.SECONDS);
}
/**
* Converts Java time to "standard Unix time".
*/
public static final long javaToUnixTime(long time) {
return TimeUnit.SECONDS.convert(time, TimeUnit.MILLISECONDS);
}
/**
* Converts DOS time to Java time (number of milliseconds since epoch).
*/
public static long dosToJavaTime(long dtime) {
@SuppressWarnings("deprecation") // Use of date constructor.
Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
(int)(((dtime >> 21) & 0x0f) - 1),
(int)((dtime >> 16) & 0x1f),
(int)((dtime >> 11) & 0x1f),
(int)((dtime >> 5) & 0x3f),
(int)((dtime << 1) & 0x3e));
return d.getTime();
}
/**
* Converts Java time to DOS time.
*/
@SuppressWarnings("deprecation") // Use of date methods
public static long javaToDosTime(long time) {
Date d = new Date(time);
int year = d.getYear() + 1900;
if (year < 1980) {
return (1 << 21) | (1 << 16);
}
return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
d.getSeconds() >> 1;
}
/**
* Fetches unsigned 16-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
public static final int get16(byte b[], int off) {
return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
}
/**
* Fetches unsigned 32-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
public static final long get32(byte b[], int off) {
return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
}
/**
* Fetches signed 64-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
public static final long get64(byte b[], int off) {
return get32(b, off) | (get32(b, off+4) << 32);
}
}

View File

@ -1158,6 +1158,9 @@ public class Cipher {
* determined from the given key, or if the given key has a keysize that * determined from the given key, or if the given key has a keysize that
* exceeds the maximum allowable keysize (as determined from the * exceeds the maximum allowable keysize (as determined from the
* configured jurisdiction policy files). * configured jurisdiction policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key) throws InvalidKeyException { public final void init(int opmode, Key key) throws InvalidKeyException {
init(opmode, key, JceSecurity.RANDOM); init(opmode, key, JceSecurity.RANDOM);
@ -1208,6 +1211,9 @@ public class Cipher {
* determined from the given key, or if the given key has a keysize that * determined from the given key, or if the given key has a keysize that
* exceeds the maximum allowable keysize (as determined from the * exceeds the maximum allowable keysize (as determined from the
* configured jurisdiction policy files). * configured jurisdiction policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key, SecureRandom random) public final void init(int opmode, Key key, SecureRandom random)
throws InvalidKeyException throws InvalidKeyException
@ -1285,6 +1291,9 @@ public class Cipher {
* algorithm parameters imply a cryptographic strength that would exceed * algorithm parameters imply a cryptographic strength that would exceed
* the legal limits (as determined from the configured jurisdiction * the legal limits (as determined from the configured jurisdiction
* policy files). * policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key, AlgorithmParameterSpec params) public final void init(int opmode, Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException throws InvalidKeyException, InvalidAlgorithmParameterException
@ -1343,6 +1352,9 @@ public class Cipher {
* algorithm parameters imply a cryptographic strength that would exceed * algorithm parameters imply a cryptographic strength that would exceed
* the legal limits (as determined from the configured jurisdiction * the legal limits (as determined from the configured jurisdiction
* policy files). * policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key, AlgorithmParameterSpec params, public final void init(int opmode, Key key, AlgorithmParameterSpec params,
SecureRandom random) SecureRandom random)
@ -1416,6 +1428,9 @@ public class Cipher {
* algorithm parameters imply a cryptographic strength that would exceed * algorithm parameters imply a cryptographic strength that would exceed
* the legal limits (as determined from the configured jurisdiction * the legal limits (as determined from the configured jurisdiction
* policy files). * policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key, AlgorithmParameters params) public final void init(int opmode, Key key, AlgorithmParameters params)
throws InvalidKeyException, InvalidAlgorithmParameterException throws InvalidKeyException, InvalidAlgorithmParameterException
@ -1474,6 +1489,9 @@ public class Cipher {
* algorithm parameters imply a cryptographic strength that would exceed * algorithm parameters imply a cryptographic strength that would exceed
* the legal limits (as determined from the configured jurisdiction * the legal limits (as determined from the configured jurisdiction
* policy files). * policy files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Key key, AlgorithmParameters params, public final void init(int opmode, Key key, AlgorithmParameters params,
SecureRandom random) SecureRandom random)
@ -1552,6 +1570,9 @@ public class Cipher {
* in the given certificate has a keysize that exceeds the maximum * in the given certificate has a keysize that exceeds the maximum
* allowable keysize (as determined by the configured jurisdiction policy * allowable keysize (as determined by the configured jurisdiction policy
* files). * files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Certificate certificate) public final void init(int opmode, Certificate certificate)
throws InvalidKeyException throws InvalidKeyException
@ -1619,6 +1640,9 @@ public class Cipher {
* in the given certificate has a keysize that exceeds the maximum * in the given certificate has a keysize that exceeds the maximum
* allowable keysize (as determined by the configured jurisdiction policy * allowable keysize (as determined by the configured jurisdiction policy
* files). * files).
* @throws UnsupportedOperationException if (@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
* by the underlying {@code CipherSpi}.
*/ */
public final void init(int opmode, Certificate certificate, public final void init(int opmode, Certificate certificate,
SecureRandom random) SecureRandom random)
@ -2410,6 +2434,9 @@ public class Cipher {
* @exception InvalidKeyException if it is impossible or unsafe to * @exception InvalidKeyException if it is impossible or unsafe to
* wrap the key with this cipher (e.g., a hardware protected key is * wrap the key with this cipher (e.g., a hardware protected key is
* being passed to a software-only cipher). * being passed to a software-only cipher).
*
* @throws UnsupportedOperationException if the corresponding method in the
* {@code CipherSpi} is not supported.
*/ */
public final byte[] wrap(Key key) public final byte[] wrap(Key key)
throws IllegalBlockSizeException, InvalidKeyException { throws IllegalBlockSizeException, InvalidKeyException {
@ -2451,6 +2478,9 @@ public class Cipher {
* @exception InvalidKeyException if <code>wrappedKey</code> does not * @exception InvalidKeyException if <code>wrappedKey</code> does not
* represent a wrapped key of type <code>wrappedKeyType</code> for * represent a wrapped key of type <code>wrappedKeyType</code> for
* the <code>wrappedKeyAlgorithm</code>. * the <code>wrappedKeyAlgorithm</code>.
*
* @throws UnsupportedOperationException if the corresponding method in the
* {@code CipherSpi} is not supported.
*/ */
public final Key unwrap(byte[] wrappedKey, public final Key unwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm, String wrappedKeyAlgorithm,

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2007, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -86,6 +86,8 @@ public class CipherInputStream extends FilterInputStream {
private int ostart = 0; private int ostart = 0;
// the offset pointing to the last "new" byte // the offset pointing to the last "new" byte
private int ofinish = 0; private int ofinish = 0;
// stream status
private boolean closed = false;
/** /**
* private convenience function. * private convenience function.
@ -293,14 +295,17 @@ public class CipherInputStream extends FilterInputStream {
* @since JCE1.2 * @since JCE1.2
*/ */
public void close() throws IOException { public void close() throws IOException {
if (closed) {
return;
}
closed = true;
input.close(); input.close();
try { try {
// throw away the unprocessed data // throw away the unprocessed data
cipher.doFinal(); cipher.doFinal();
} }
catch (BadPaddingException ex) { catch (BadPaddingException | IllegalBlockSizeException ex) {
}
catch (IllegalBlockSizeException ex) {
} }
ostart = 0; ostart = 0;
ofinish = 0; ofinish = 0;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2007, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,6 +74,9 @@ public class CipherOutputStream extends FilterOutputStream {
// the buffer holding data ready to be written out // the buffer holding data ready to be written out
private byte[] obuffer; private byte[] obuffer;
// stream status
private boolean closed = false;
/** /**
* *
* Constructs a CipherOutputStream from an OutputStream and a * Constructs a CipherOutputStream from an OutputStream and a
@ -198,11 +201,14 @@ public class CipherOutputStream extends FilterOutputStream {
* @since JCE1.2 * @since JCE1.2
*/ */
public void close() throws IOException { public void close() throws IOException {
if (closed) {
return;
}
closed = true;
try { try {
obuffer = cipher.doFinal(); obuffer = cipher.doFinal();
} catch (IllegalBlockSizeException e) { } catch (IllegalBlockSizeException | BadPaddingException e) {
obuffer = null;
} catch (BadPaddingException e) {
obuffer = null; obuffer = null;
} }
try { try {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -347,6 +347,9 @@ public abstract class CipherSpi {
* initializing this cipher, or requires * initializing this cipher, or requires
* algorithm parameters that cannot be * algorithm parameters that cannot be
* determined from the given key. * determined from the given key.
* @throws UnsupportedOperationException if {@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
* by the cipher.
*/ */
protected abstract void engineInit(int opmode, Key key, protected abstract void engineInit(int opmode, Key key,
SecureRandom random) SecureRandom random)
@ -399,6 +402,9 @@ public abstract class CipherSpi {
* parameters are inappropriate for this cipher, * parameters are inappropriate for this cipher,
* or if this cipher requires * or if this cipher requires
* algorithm parameters and <code>params</code> is null. * algorithm parameters and <code>params</code> is null.
* @throws UnsupportedOperationException if {@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
* by the cipher.
*/ */
protected abstract void engineInit(int opmode, Key key, protected abstract void engineInit(int opmode, Key key,
AlgorithmParameterSpec params, AlgorithmParameterSpec params,
@ -452,6 +458,9 @@ public abstract class CipherSpi {
* parameters are inappropriate for this cipher, * parameters are inappropriate for this cipher,
* or if this cipher requires * or if this cipher requires
* algorithm parameters and <code>params</code> is null. * algorithm parameters and <code>params</code> is null.
* @throws UnsupportedOperationException if {@code opmode} is
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
* by the cipher.
*/ */
protected abstract void engineInit(int opmode, Key key, protected abstract void engineInit(int opmode, Key key,
AlgorithmParameters params, AlgorithmParameters params,
@ -863,6 +872,8 @@ public abstract class CipherSpi {
* @exception InvalidKeyException if it is impossible or unsafe to * @exception InvalidKeyException if it is impossible or unsafe to
* wrap the key with this cipher (e.g., a hardware protected key is * wrap the key with this cipher (e.g., a hardware protected key is
* being passed to a software-only cipher). * being passed to a software-only cipher).
*
* @throws UnsupportedOperationException if this method is not supported.
*/ */
protected byte[] engineWrap(Key key) protected byte[] engineWrap(Key key)
throws IllegalBlockSizeException, InvalidKeyException throws IllegalBlockSizeException, InvalidKeyException
@ -899,6 +910,8 @@ public abstract class CipherSpi {
* @exception InvalidKeyException if <code>wrappedKey</code> does not * @exception InvalidKeyException if <code>wrappedKey</code> does not
* represent a wrapped key of type <code>wrappedKeyType</code> for * represent a wrapped key of type <code>wrappedKeyType</code> for
* the <code>wrappedKeyAlgorithm</code>. * the <code>wrappedKeyAlgorithm</code>.
*
* @throws UnsupportedOperationException if this method is not supported.
*/ */
protected Key engineUnwrap(byte[] wrappedKey, protected Key engineUnwrap(byte[] wrappedKey,
String wrappedKeyAlgorithm, String wrappedKeyAlgorithm,

View File

@ -0,0 +1,159 @@
/*
* 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.management;
/**
* Diagnostic Command Argument information. It contains the description
* of one parameter of the diagnostic command. A parameter can either be an
* option or an argument. Options are identified by the option name while
* arguments are identified by their position in the command line. The generic
* syntax of a diagnostic command is:
* <blockquote>
* &lt;command name&gt; [&lt;option&gt;=&lt;value&gt;] [&lt;argument_value&gt;]
* </blockquote>
* Example:
* <blockquote>
* command_name option1=value1 option2=value argumentA argumentB argumentC
* </blockquote>
* In this command line, the diagnostic command receives five parameters, two
* options named {@code option1} and {@code option2}, and three arguments.
* argumentA's position is 0, argumentB's position is 1 and argumentC's
* position is 2.
*
* @since 8
*/
class DiagnosticCommandArgumentInfo {
private final String name;
private final String description;
private final String type;
private final String defaultValue;
private final boolean mandatory;
private final boolean option;
private final boolean multiple;
private final int position;
/**
* Returns the argument name.
*
* @return the argument name
*/
String getName() {
return name;
}
/**
* Returns the argument description.
*
* @return the argument description
*/
String getDescription() {
return description;
}
/**
* Returns the argument type.
*
* @return the argument type
*/
String getType() {
return type;
}
/**
* Returns the default value as a String if a default value
* is defined, null otherwise.
*
* @return the default value as a String if a default value
* is defined, null otherwise.
*/
String getDefault() {
return defaultValue;
}
/**
* Returns {@code true} if the argument is mandatory,
* {@code false} otherwise.
*
* @return {@code true} if the argument is mandatory,
* {@code false} otherwise
*/
boolean isMandatory() {
return mandatory;
}
/**
* Returns {@code true} if the argument is an option,
* {@code false} otherwise. Options have to be specified using the
* &lt;key&gt;=&lt;value&gt; syntax on the command line, while other
* arguments are specified with a single &lt;value&gt; field and are
* identified by their position on command line.
*
* @return {@code true} if the argument is an option,
* {@code false} otherwise
*/
boolean isOption() {
return option;
}
/**
* Returns {@code true} if the argument can be specified multiple times,
* {@code false} otherwise.
*
* @return {@code true} if the argument can be specified multiple times,
* {@code false} otherwise
*/
boolean isMultiple() {
return multiple;
}
/**
* Returns the expected position of this argument if it is not an option,
* -1 otherwise. Argument position if defined from left to right,
* starting at zero and ignoring the diagnostic command name and
* options.
*
* @return the expected position of this argument if it is not an option,
* -1 otherwise.
*/
int getPosition() {
return position;
}
DiagnosticCommandArgumentInfo(String name, String description,
String type, String defaultValue,
boolean mandatory, boolean option,
boolean multiple, int position) {
this.name = name;
this.description = description;
this.type = type;
this.defaultValue = defaultValue;
this.mandatory = mandatory;
this.option = option;
this.multiple = multiple;
this.position = position;
}
}

View File

@ -0,0 +1,380 @@
/*
* 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.management;
import com.sun.management.DiagnosticCommandMBean;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Permission;
import java.util.*;
import javax.management.*;
/**
* Implementation class for the diagnostic commands subsystem.
*
* @since 8
*/
class DiagnosticCommandImpl extends NotificationEmitterSupport
implements DiagnosticCommandMBean {
private final VMManagement jvm;
private volatile Map<String, Wrapper> wrappers = null;
private static final String strClassName = "".getClass().getName();
private static final String strArrayClassName = String[].class.getName();
private final boolean isSupported;
@Override
public Object getAttribute(String attribute) throws AttributeNotFoundException,
MBeanException, ReflectionException {
throw new AttributeNotFoundException(attribute);
}
@Override
public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
InvalidAttributeValueException, MBeanException, ReflectionException {
throw new AttributeNotFoundException(attribute.getName());
}
@Override
public AttributeList getAttributes(String[] attributes) {
return new AttributeList();
}
@Override
public AttributeList setAttributes(AttributeList attributes) {
return new AttributeList();
}
private class Wrapper {
String name;
String cmd;
DiagnosticCommandInfo info;
Permission permission;
Wrapper(String name, String cmd, DiagnosticCommandInfo info)
throws InstantiationException {
this.name = name;
this.cmd = cmd;
this.info = info;
this.permission = null;
Exception cause = null;
if (info.getPermissionClass() != null) {
try {
Class c = Class.forName(info.getPermissionClass());
if (info.getPermissionAction() == null) {
try {
Constructor constructor = c.getConstructor(String.class);
permission = (Permission) constructor.newInstance(info.getPermissionName());
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException ex) {
cause = ex;
}
}
if (permission == null) {
try {
Constructor constructor = c.getConstructor(String.class, String.class);
permission = (Permission) constructor.newInstance(
info.getPermissionName(),
info.getPermissionAction());
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException ex) {
cause = ex;
}
}
} catch (ClassNotFoundException ex) { }
if (permission == null) {
InstantiationException iex =
new InstantiationException("Unable to instantiate required permission");
iex.initCause(cause);
}
}
}
public String execute(String[] args) {
if (permission != null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(permission);
}
}
if(args == null) {
return executeDiagnosticCommand(cmd);
} else {
StringBuilder sb = new StringBuilder();
sb.append(cmd);
for(int i=0; i<args.length; i++) {
if(args[i] == null) {
throw new IllegalArgumentException("Invalid null argument");
}
sb.append(" ");
sb.append(args[i]);
}
return executeDiagnosticCommand(sb.toString());
}
}
}
DiagnosticCommandImpl(VMManagement jvm) {
this.jvm = jvm;
isSupported = jvm.isRemoteDiagnosticCommandsSupported();
}
private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
@Override
public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
return o1.getName().compareTo(o2.getName());
}
}
@Override
public MBeanInfo getMBeanInfo() {
SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
Map<String, Wrapper> wrappersmap;
if (!isSupported) {
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
} else {
try {
String[] command = getDiagnosticCommands();
DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
new MBeanParameterInfo("arguments", strArrayClassName,
"Array of Diagnostic Commands Arguments and Options")
};
wrappersmap = new HashMap<>();
for (int i = 0; i < command.length; i++) {
String name = transform(command[i]);
try {
Wrapper w = new Wrapper(name, command[i], info[i]);
wrappersmap.put(name, w);
operations.add(new MBeanOperationInfo(
w.name,
w.info.getDescription(),
(w.info.getArgumentsInfo() == null
|| w.info.getArgumentsInfo().isEmpty())
? null : stringArgInfo,
strClassName,
MBeanOperationInfo.ACTION_INFO,
commandDescriptor(w)));
} catch (InstantiationException ex) {
// If for some reasons the creation of a diagnostic command
// wrappers fails, the diagnostic command is just ignored
// and won't appear in the DynamicMBean
}
}
} catch (IllegalArgumentException | UnsupportedOperationException e) {
wrappersmap = (Map<String, Wrapper>) Collections.EMPTY_MAP;
}
}
wrappers = Collections.unmodifiableMap(wrappersmap);
HashMap<String, Object> map = new HashMap<>();
map.put("immutableInfo", "false");
map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
map.put("mxbean", "false");
Descriptor desc = new ImmutableDescriptor(map);
return new MBeanInfo(
this.getClass().getName(),
"Diagnostic Commands",
null, // attributes
null, // constructors
operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
getNotificationInfo(), // notifications
desc);
}
@Override
public Object invoke(String actionName, Object[] params, String[] signature)
throws MBeanException, ReflectionException {
if (!isSupported) {
throw new UnsupportedOperationException();
}
if (wrappers == null) {
getMBeanInfo();
}
Wrapper w = wrappers.get(actionName);
if (w != null) {
if (w.info.getArgumentsInfo().isEmpty()
&& (params == null || params.length == 0)
&& (signature == null || signature.length == 0)) {
return w.execute(null);
} else if((params != null && params.length == 1)
&& (signature != null && signature.length == 1
&& signature[0] != null
&& signature[0].compareTo(strArrayClassName) == 0)) {
return w.execute((String[]) params[0]);
}
}
throw new ReflectionException(new NoSuchMethodException(actionName));
}
private static String transform(String name) {
StringBuilder sb = new StringBuilder();
boolean toLower = true;
boolean toUpper = false;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '.' || c == '_') {
toLower = false;
toUpper = true;
} else {
if (toUpper) {
toUpper = false;
sb.append(Character.toUpperCase(c));
} else if(toLower) {
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
}
return sb.toString();
}
private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
HashMap<String, Object> map = new HashMap<>();
map.put("dcmd.name", w.info.getName());
map.put("dcmd.description", w.info.getDescription());
map.put("dcmd.vmImpact", w.info.getImpact());
map.put("dcmd.permissionClass", w.info.getPermissionClass());
map.put("dcmd.permissionName", w.info.getPermissionName());
map.put("dcmd.permissionAction", w.info.getPermissionAction());
map.put("dcmd.enabled", w.info.isEnabled());
StringBuilder sb = new StringBuilder();
sb.append("help ");
sb.append(w.info.getName());
map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
HashMap<String, Object> allargmap = new HashMap<>();
for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
HashMap<String, Object> argmap = new HashMap<>();
argmap.put("dcmd.arg.name", arginfo.getName());
argmap.put("dcmd.arg.type", arginfo.getType());
argmap.put("dcmd.arg.description", arginfo.getDescription());
argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
boolean isOption = arginfo.isOption();
argmap.put("dcmd.arg.isOption", isOption);
if(!isOption) {
argmap.put("dcmd.arg.position", arginfo.getPosition());
} else {
argmap.put("dcmd.arg.position", -1);
}
allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
}
map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
}
return new ImmutableDescriptor(map);
}
private final static String notifName =
"javax.management.Notification";
private final static String[] diagFramNotifTypes = {
"jmx.mbean.info.changed"
};
private MBeanNotificationInfo[] notifInfo = null;
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
synchronized (this) {
if (notifInfo == null) {
notifInfo = new MBeanNotificationInfo[1];
notifInfo[0] =
new MBeanNotificationInfo(diagFramNotifTypes,
notifName,
"Diagnostic Framework Notification");
}
}
return notifInfo;
}
private static long seqNumber = 0;
private static long getNextSeqNumber() {
return ++seqNumber;
}
private void createDiagnosticFrameworkNotification() {
if (!hasListeners()) {
return;
}
ObjectName on = null;
try {
on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME);
} catch (MalformedObjectNameException e) { }
Notification notif = new Notification("jmx.mbean.info.changed",
on,
getNextSeqNumber());
notif.setUserData(getMBeanInfo());
sendNotification(notif);
}
@Override
public synchronized void addNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback) {
boolean before = hasListeners();
super.addNotificationListener(listener, filter, handback);
boolean after = hasListeners();
if (!before && after) {
setNotificationEnabled(true);
}
}
@Override
public synchronized void removeNotificationListener(NotificationListener listener)
throws ListenerNotFoundException {
boolean before = hasListeners();
super.removeNotificationListener(listener);
boolean after = hasListeners();
if (before && !after) {
setNotificationEnabled(false);
}
}
@Override
public synchronized void removeNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback)
throws ListenerNotFoundException {
boolean before = hasListeners();
super.removeNotificationListener(listener, filter, handback);
boolean after = hasListeners();
if (before && !after) {
setNotificationEnabled(false);
}
}
private native void setNotificationEnabled(boolean enabled);
private native String[] getDiagnosticCommands();
private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
private native String executeDiagnosticCommand(String command);
}

View File

@ -0,0 +1,151 @@
/*
* 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.management;
import java.util.List;
/**
* Diagnostic command information. It contains the description of a
* diagnostic command.
*
* @since 8
*/
class DiagnosticCommandInfo {
private final String name;
private final String description;
private final String impact;
private final String permissionClass;
private final String permissionName;
private final String permissionAction;
private final boolean enabled;
private final List<DiagnosticCommandArgumentInfo> arguments;
/**
* Returns the diagnostic command name.
*
* @return the diagnostic command name
*/
String getName() {
return name;
}
/**
* Returns the diagnostic command description.
*
* @return the diagnostic command description
*/
String getDescription() {
return description;
}
/**
* Returns the potential impact of the diagnostic command execution
* on the Java virtual machine behavior.
*
* @return the potential impact of the diagnostic command execution
* on the Java virtual machine behavior
*/
String getImpact() {
return impact;
}
/**
* Returns the name of the permission class required to be allowed
* to invoke the diagnostic command, or null if no permission
* is required.
*
* @return the name of the permission class name required to be allowed
* to invoke the diagnostic command, or null if no permission
* is required
*/
String getPermissionClass() {
return permissionClass;
}
/**
* Returns the permission name required to be allowed to invoke the
* diagnostic command, or null if no permission is required.
*
* @return the permission name required to be allowed to invoke the
* diagnostic command, or null if no permission is required
*/
String getPermissionName() {
return permissionName;
}
/**
* Returns the permission action required to be allowed to invoke the
* diagnostic command, or null if no permission is required or
* if the permission has no action specified.
*
* @return the permission action required to be allowed to invoke the
* diagnostic command, or null if no permission is required or
* if the permission has no action specified
*/
String getPermissionAction() {
return permissionAction;
}
/**
* Returns {@code true} if the diagnostic command is enabled,
* {@code false} otherwise. The enabled/disabled
* status of a diagnostic command can evolve during
* the lifetime of the Java virtual machine.
*
* @return {@code true} if the diagnostic command is enabled,
* {@code false} otherwise
*/
boolean isEnabled() {
return enabled;
}
/**
* Returns the list of the diagnostic command arguments description.
* If the diagnostic command has no arguments, it returns an empty list.
*
* @return a list of the diagnostic command arguments description
*/
List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
return arguments;
}
DiagnosticCommandInfo(String name, String description,
String impact, String permissionClass,
String permissionName, String permissionAction,
boolean enabled,
List<DiagnosticCommandArgumentInfo> arguments)
{
this.name = name;
this.description = description;
this.impact = impact;
this.permissionClass = permissionClass;
this.permissionName = permissionName;
this.permissionAction = permissionAction;
this.enabled = enabled;
this.arguments = arguments;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ package sun.management;
import java.lang.management.*; import java.lang.management.*;
import javax.management.DynamicMBean;
import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException; import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer; import javax.management.MBeanServer;
@ -42,7 +43,9 @@ import sun.util.logging.LoggingSupport;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import com.sun.management.DiagnosticCommandMBean;
import com.sun.management.OSMBeanFactory; import com.sun.management.OSMBeanFactory;
import com.sun.management.HotSpotDiagnosticMXBean; import com.sun.management.HotSpotDiagnosticMXBean;
@ -263,6 +266,7 @@ public class ManagementFactoryHelper {
private static HotspotThread hsThreadMBean = null; private static HotspotThread hsThreadMBean = null;
private static HotspotCompilation hsCompileMBean = null; private static HotspotCompilation hsCompileMBean = null;
private static HotspotMemory hsMemoryMBean = null; private static HotspotMemory hsMemoryMBean = null;
private static DiagnosticCommandImpl hsDiagCommandMBean = null;
public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
if (hsDiagMBean == null) { if (hsDiagMBean == null) {
@ -311,6 +315,14 @@ public class ManagementFactoryHelper {
return hsMemoryMBean; return hsMemoryMBean;
} }
public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() {
// Remote Diagnostic Commands may not be supported
if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) {
hsDiagCommandMBean = new DiagnosticCommandImpl(jvm);
}
return hsDiagCommandMBean;
}
/** /**
* This method is for testing only. * This method is for testing only.
*/ */
@ -365,6 +377,18 @@ public class ManagementFactoryHelper {
private final static String HOTSPOT_THREAD_MBEAN_NAME = private final static String HOTSPOT_THREAD_MBEAN_NAME =
"sun.management:type=HotspotThreading"; "sun.management:type=HotspotThreading";
final static String HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
public static HashMap<ObjectName, DynamicMBean> getPlatformDynamicMBeans() {
HashMap<ObjectName, DynamicMBean> map = new HashMap<>();
DiagnosticCommandMBean diagMBean = getDiagnosticCommandMBean();
if (diagMBean != null) {
map.put(Util.newObjectName(HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME), diagMBean);
}
return map;
}
static void registerInternalMBeans(MBeanServer mbs) { static void registerInternalMBeans(MBeanServer mbs) {
// register all internal MBeans if not registered // register all internal MBeans if not registered
// No exception is thrown if a MBean with that object name // No exception is thrown if a MBean with that object name

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2011, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,6 +46,7 @@ public interface VMManagement {
public boolean isThreadAllocatedMemorySupported(); public boolean isThreadAllocatedMemorySupported();
public boolean isThreadAllocatedMemoryEnabled(); public boolean isThreadAllocatedMemoryEnabled();
public boolean isGcNotificationSupported(); public boolean isGcNotificationSupported();
public boolean isRemoteDiagnosticCommandsSupported();
// Class Loading Subsystem // Class Loading Subsystem
public long getTotalClassCount(); public long getTotalClassCount();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2011, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -57,6 +57,7 @@ class VMManagementImpl implements VMManagement {
private static boolean synchronizerUsageSupport; private static boolean synchronizerUsageSupport;
private static boolean threadAllocatedMemorySupport; private static boolean threadAllocatedMemorySupport;
private static boolean gcNotificationSupport; private static boolean gcNotificationSupport;
private static boolean remoteDiagnosticCommandsSupport;
static { static {
@ -106,6 +107,10 @@ class VMManagementImpl implements VMManagement {
return gcNotificationSupport; return gcNotificationSupport;
} }
public boolean isRemoteDiagnosticCommandsSupported() {
return remoteDiagnosticCommandsSupport;
}
public native boolean isThreadContentionMonitoringEnabled(); public native boolean isThreadContentionMonitoringEnabled();
public native boolean isThreadCpuTimeEnabled(); public native boolean isThreadCpuTimeEnabled();
public native boolean isThreadAllocatedMemoryEnabled(); public native boolean isThreadAllocatedMemoryEnabled();

View File

@ -60,9 +60,12 @@ public final class JdpPacketWriter {
*/ */
public void addEntry(String entry) public void addEntry(String entry)
throws IOException { throws IOException {
pkt.writeShort(entry.length()); /* DataOutputStream.writeUTF() do essentially
byte[] b = entry.getBytes("UTF-8"); * the same as:
pkt.write(b); * pkt.writeShort(entry.getBytes("UTF-8").length);
* pkt.write(entry.getBytes("UTF-8"));
*/
pkt.writeUTF(entry);
} }
/** /**

View File

@ -31,7 +31,42 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* This annotation marks classes and fields as considered to be contended. * <p>An annotation expressing that objects and/or their fields are
* expected to encounter memory contention, generally in the form of
* "false sharing". This annotation serves as a hint that such objects
* and fields should reside in locations isolated from those of other
* objects or fields. Susceptibility to memory contention is a
* property of the intended usages of objects and fields, not their
* types or qualifiers. The effects of this annotation will nearly
* always add significant space overhead to objects. The use of
* {@code @Contended} is warranted only when the performance impact of
* this time/space tradeoff is intrinsically worthwhile; for example,
* in concurrent contexts in which each instance of the annotated
* class is often accessed by a different thread.
*
* <p>A {@code @Contended} field annotation may optionally include a
* <i>contention group</i> tag. A contention group defines a set of one
* or more fields that collectively must be isolated from all other
* contention groups. The fields in the same contention group may not be
* pairwise isolated. With no contention group tag (or with the default
* empty tag: "") each {@code @Contended} field resides in its own
* <i>distinct</i> and <i>anonymous</i> contention group.
*
* <p>When the annotation is used at the class level, the effect is
* equivalent to grouping all the declared fields not already having the
* {@code @Contended} annotation into the same anonymous group.
* With the class level annotation, implementations may choose different
* isolation techniques, such as isolating the entire object, rather than
* isolating distinct fields. A contention group tag has no meaning
* in a class level {@code @Contended} annotation, and is ignored.
*
* <p>The class level {@code @Contended} annotation is not inherited and has
* no effect on the fields declared in any sub-classes. The effects of all
* {@code @Contended} annotations, however, remain in force for all
* subclass instances, providing isolation of all the defined contention
* groups. Contention group tags are not inherited, and the same tag used
* in a superclass and subclass, represent distinct contention groups.
*
* @since 1.8 * @since 1.8
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@ -39,7 +74,10 @@ import java.lang.annotation.Target;
public @interface Contended { public @interface Contended {
/** /**
Defines the contention group tag. * The (optional) contention group tag.
* This tag is only meaningful for field level annotations.
*
* @return contention group tag.
*/ */
String value() default ""; String value() default "";
} }

View File

@ -24,7 +24,7 @@
*/ */
package sun.misc; package sun.misc;
import java.util.Random; import java.util.concurrent.ThreadLocalRandom;
/** /**
* Hashing utilities. * Hashing utilities.
@ -207,28 +207,16 @@ public class Hashing {
} }
/** /**
* Holds references to things that can't be initialized until after VM * Return a non-zero 32-bit pseudo random value. The {@code instance} object
* is fully booted. * may be used as part of the value.
*
* @param instance an object to use if desired in choosing value.
* @return a non-zero 32-bit pseudo random value.
*/ */
private static class Holder {
/**
* Used for generating per-instance hash seeds.
*
* We try to improve upon the default seeding.
*/
static final Random SEED_MAKER = new Random(
Double.doubleToRawLongBits(Math.random())
^ System.identityHashCode(Hashing.class)
^ System.currentTimeMillis()
^ System.nanoTime()
^ Runtime.getRuntime().freeMemory());
}
public static int randomHashSeed(Object instance) { public static int randomHashSeed(Object instance) {
int seed; int seed;
if (sun.misc.VM.isBooted()) { if (sun.misc.VM.isBooted()) {
seed = Holder.SEED_MAKER.nextInt(); seed = ThreadLocalRandom.current().nextInt();
} else { } else {
// lower quality "random" seed value--still better than zero and not // lower quality "random" seed value--still better than zero and not
// not practically reversible. // not practically reversible.

View File

@ -3158,6 +3158,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
private boolean marked = false; private boolean marked = false;
private int inCache = 0; private int inCache = 0;
private int markCount = 0; private int markCount = 0;
private boolean closed; // false
public HttpInputStream (InputStream is) { public HttpInputStream (InputStream is) {
super (is); super (is);
@ -3233,8 +3234,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
} }
} }
private void ensureOpen() throws IOException {
if (closed)
throw new IOException("stream is closed");
}
@Override @Override
public int read() throws IOException { public int read() throws IOException {
ensureOpen();
try { try {
byte[] b = new byte[1]; byte[] b = new byte[1];
int ret = read(b); int ret = read(b);
@ -3254,6 +3261,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
@Override @Override
public int read(byte[] b, int off, int len) throws IOException { public int read(byte[] b, int off, int len) throws IOException {
ensureOpen();
try { try {
int newLen = super.read(b, off, len); int newLen = super.read(b, off, len);
int nWrite; int nWrite;
@ -3291,7 +3299,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
@Override @Override
public long skip (long n) throws IOException { public long skip (long n) throws IOException {
ensureOpen();
long remaining = n; long remaining = n;
int nr; int nr;
if (skipBuffer == null) if (skipBuffer == null)
@ -3317,6 +3325,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
@Override @Override
public void close () throws IOException { public void close () throws IOException {
if (closed)
return;
try { try {
if (outputStream != null) { if (outputStream != null) {
if (read() != -1) { if (read() != -1) {
@ -3332,6 +3343,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
} }
throw ioex; throw ioex;
} finally { } finally {
closed = true;
HttpURLConnection.this.http = null; HttpURLConnection.this.http = null;
checkResponseCredentials (true); checkResponseCredentials (true);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -330,7 +330,7 @@ final class P11KeyAgreement extends KeyAgreementSpi {
// as here we always retrieve the CKA_VALUE even for tokens // as here we always retrieve the CKA_VALUE even for tokens
// that do not have that bug. // that do not have that bug.
byte[] keyBytes = key.getEncoded(); byte[] keyBytes = key.getEncoded();
byte[] newBytes = P11Util.trimZeroes(keyBytes); byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
if (keyBytes != newBytes) { if (keyBytes != newBytes) {
key = new SecretKeySpec(newBytes, algorithm); key = new SecretKeySpec(newBytes, algorithm);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,7 @@ import sun.security.rsa.RSAPadding;
import sun.security.pkcs11.wrapper.*; import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.KeyUtil;
/** /**
* Signature implementation class. This class currently supports the * Signature implementation class. This class currently supports the
@ -697,8 +698,8 @@ final class P11Signature extends SignatureSpi {
BigInteger r = values[0].getPositiveBigInteger(); BigInteger r = values[0].getPositiveBigInteger();
BigInteger s = values[1].getPositiveBigInteger(); BigInteger s = values[1].getPositiveBigInteger();
// trim leading zeroes // trim leading zeroes
byte[] br = P11Util.trimZeroes(r.toByteArray()); byte[] br = KeyUtil.trimZeroes(r.toByteArray());
byte[] bs = P11Util.trimZeroes(s.toByteArray()); byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
int k = Math.max(br.length, bs.length); int k = Math.max(br.length, bs.length);
// r and s each occupy half the array // r and s each occupy half the array
byte[] res = new byte[k << 1]; byte[] res = new byte[k << 1];

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2011, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -131,20 +131,6 @@ public final class P11Util {
return b; return b;
} }
// trim leading (most significant) zeroes from the result
static byte[] trimZeroes(byte[] b) {
int i = 0;
while ((i < b.length - 1) && (b[i] == 0)) {
i++;
}
if (i == 0) {
return b;
}
byte[] t = new byte[b.length - i];
System.arraycopy(b, i, t, 0, t.length);
return t;
}
public static byte[] getMagnitude(BigInteger bi) { public static byte[] getMagnitude(BigInteger bi) {
byte[] b = bi.toByteArray(); byte[] b = bi.toByteArray();
if ((b.length > 1) && (b[0] == 0)) { if ((b.length > 1) && (b[0] == 0)) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -200,5 +200,24 @@ public final class KeyUtil {
// Don't bother to check against the y^q mod p if safe primes are used. // Don't bother to check against the y^q mod p if safe primes are used.
} }
/**
* Trim leading (most significant) zeroes from the result.
*
* @throws NullPointerException if {@code b} is null
*/
public static byte[] trimZeroes(byte[] b) {
int i = 0;
while ((i < b.length - 1) && (b[i] == 0)) {
i++;
}
if (i == 0) {
return b;
}
byte[] t = new byte[b.length - i];
System.arraycopy(b, i, t, 0, t.length);
return t;
}
} }

View File

@ -360,6 +360,8 @@ class SummaryTab extends Tab {
Math.min(99F, Math.min(99F,
elapsedCpu / (elapsedTime * 10000F * result.nCPUs)); elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
cpuUsage = Math.max(0F, cpuUsage);
getPlotter().addValues(result.timeStamp, getPlotter().addValues(result.timeStamp,
Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS))); Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT, getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,

View File

@ -25,6 +25,11 @@
package sun.util.locale.provider; package sun.util.locale.provider;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
/** /**
* FallbackProviderAdapter implementation. * FallbackProviderAdapter implementation.
* *
@ -32,6 +37,18 @@ package sun.util.locale.provider;
*/ */
public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter { public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
/**
* Supported language tag set.
*/
private static final Set<String> rootTagSet =
Collections.singleton(Locale.ROOT.toLanguageTag());
/**
* Fallback provider only provides the ROOT locale data.
*/
private final LocaleResources rootLocaleResources =
new LocaleResources(this, Locale.ROOT);
/** /**
* Returns the type of this LocaleProviderAdapter * Returns the type of this LocaleProviderAdapter
*/ */
@ -39,4 +56,14 @@ public class FallbackLocaleProviderAdapter extends JRELocaleProviderAdapter {
public LocaleProviderAdapter.Type getAdapterType() { public LocaleProviderAdapter.Type getAdapterType() {
return Type.FALLBACK; return Type.FALLBACK;
} }
@Override
public LocaleResources getLocaleResources(Locale locale) {
return rootLocaleResources;
}
@Override
protected Set<String> createLanguageTagSet(String category) {
return rootTagSet;
}
} }

View File

@ -34,12 +34,10 @@ import java.text.spi.DateFormatProvider;
import java.text.spi.DateFormatSymbolsProvider; import java.text.spi.DateFormatSymbolsProvider;
import java.text.spi.DecimalFormatSymbolsProvider; import java.text.spi.DecimalFormatSymbolsProvider;
import java.text.spi.NumberFormatProvider; import java.text.spi.NumberFormatProvider;
import java.util.Calendar;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.spi.CalendarDataProvider; import java.util.spi.CalendarDataProvider;

View File

@ -119,6 +119,12 @@ public abstract class LocaleProviderAdapter {
*/ */
private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null; private static LocaleProviderAdapter fallbackLocaleProviderAdapter = null;
/**
* Default fallback adapter type, which should return something meaningful in any case.
* This is either JRE or FALLBACK.
*/
static LocaleProviderAdapter.Type defaultLocaleProviderAdapter = null;
/** /**
* Adapter lookup cache. * Adapter lookup cache.
*/ */
@ -140,13 +146,19 @@ public abstract class LocaleProviderAdapter {
// load adapter if necessary // load adapter if necessary
switch (aType) { switch (aType) {
case CLDR: case CLDR:
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter(); if (cldrLocaleProviderAdapter == null) {
cldrLocaleProviderAdapter = new CLDRLocaleProviderAdapter();
}
break; break;
case HOST: case HOST:
hostLocaleProviderAdapter = new HostLocaleProviderAdapter(); if (hostLocaleProviderAdapter == null) {
hostLocaleProviderAdapter = new HostLocaleProviderAdapter();
}
break; break;
} }
typeList.add(aType); if (!typeList.contains(aType)) {
typeList.add(aType);
}
} catch (IllegalArgumentException | UnsupportedOperationException e) { } catch (IllegalArgumentException | UnsupportedOperationException e) {
// could be caused by the user specifying wrong // could be caused by the user specifying wrong
// provider name or format in the system property // provider name or format in the system property
@ -160,11 +172,15 @@ public abstract class LocaleProviderAdapter {
// Append FALLBACK as the last resort. // Append FALLBACK as the last resort.
fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter(); fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
typeList.add(Type.FALLBACK); typeList.add(Type.FALLBACK);
defaultLocaleProviderAdapter = Type.FALLBACK;
} else {
defaultLocaleProviderAdapter = Type.JRE;
} }
} else { } else {
// Default preference list // Default preference list
typeList.add(Type.JRE); typeList.add(Type.JRE);
typeList.add(Type.SPI); typeList.add(Type.SPI);
defaultLocaleProviderAdapter = Type.JRE;
} }
adapterPreference = Collections.unmodifiableList(typeList); adapterPreference = Collections.unmodifiableList(typeList);

View File

@ -127,32 +127,13 @@ public final class LocaleServiceProviderPool {
private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) { private LocaleServiceProviderPool (final Class<? extends LocaleServiceProvider> c) {
providerClass = c; providerClass = c;
// Add the JRE Locale Data Adapter implementation. for (LocaleProviderAdapter.Type type : LocaleProviderAdapter.getAdapterPreference()) {
providers.putIfAbsent(LocaleProviderAdapter.Type.JRE, LocaleProviderAdapter lda = LocaleProviderAdapter.forType(type);
LocaleProviderAdapter.forJRE().getLocaleServiceProvider(c)); if (lda != null) {
LocaleServiceProvider provider = lda.getLocaleServiceProvider(c);
// Add the SPI Locale Data Adapter implementation. if (provider != null) {
LocaleProviderAdapter lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.SPI); providers.putIfAbsent(type, provider);
LocaleServiceProvider provider = lda.getLocaleServiceProvider(c); }
if (provider != null) {
providers.putIfAbsent(LocaleProviderAdapter.Type.SPI, provider);
}
// Add the CLDR Locale Data Adapter implementation, if needed.
lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.CLDR);
if (lda != null) {
provider = lda.getLocaleServiceProvider(c);
if (provider != null) {
providers.putIfAbsent(LocaleProviderAdapter.Type.CLDR, provider);
}
}
// Add the Host Locale Data Adapter implementation, if needed.
lda = LocaleProviderAdapter.forType(LocaleProviderAdapter.Type.HOST);
if (lda != null) {
provider = lda.getLocaleServiceProvider(c);
if (provider != null) {
providers.putIfAbsent(LocaleProviderAdapter.Type.HOST, provider);
} }
} }
} }
@ -246,7 +227,8 @@ public final class LocaleServiceProviderPool {
*/ */
boolean hasProviders() { boolean hasProviders() {
return providers.size() != 1 || return providers.size() != 1 ||
providers.get(LocaleProviderAdapter.Type.JRE) == null; (providers.get(LocaleProviderAdapter.Type.JRE) == null &&
providers.get(LocaleProviderAdapter.Type.FALLBACK) == null);
} }
/** /**
@ -296,9 +278,8 @@ public final class LocaleServiceProviderPool {
// Check whether JRE is the sole locale data provider or not, // Check whether JRE is the sole locale data provider or not,
// and directly call it if it is. // and directly call it if it is.
if (!hasProviders()) { if (!hasProviders()) {
return getter.getObject( return getter.getObject((P)providers.get(LocaleProviderAdapter.defaultLocaleProviderAdapter),
(P)providers.get(LocaleProviderAdapter.Type.JRE), locale, key, params);
locale, key, params);
} }
List<Locale> lookupLocales = getLookupLocales(locale); List<Locale> lookupLocales = getLookupLocales(locale);

View File

@ -1818,7 +1818,7 @@ public class ZipFileSystem extends FileSystem {
Entry(byte[] name) { Entry(byte[] name) {
name(name); name(name);
this.mtime = System.currentTimeMillis(); this.mtime = this.ctime = this.atime = System.currentTimeMillis();
this.crc = 0; this.crc = 0;
this.size = 0; this.size = 0;
this.csize = 0; this.csize = 0;
@ -1912,17 +1912,18 @@ public class ZipFileSystem extends FileSystem {
{ {
int written = CENHDR; int written = CENHDR;
int version0 = version(); int version0 = version();
long csize0 = csize; long csize0 = csize;
long size0 = size; long size0 = size;
long locoff0 = locoff; long locoff0 = locoff;
int elen64 = 0; // extra for ZIP64 int elen64 = 0; // extra for ZIP64
int elenNTFS = 0; // extra for NTFS (a/c/mtime) int elenNTFS = 0; // extra for NTFS (a/c/mtime)
int elenEXTT = 0; // extra for Extended Timestamp int elenEXTT = 0; // extra for Extended Timestamp
boolean foundExtraTime = false; // if time stamp NTFS, EXTT present
// confirm size/length // confirm size/length
int nlen = (name != null) ? name.length : 0; int nlen = (name != null) ? name.length : 0;
int elen = (extra != null) ? extra.length : 0; int elen = (extra != null) ? extra.length : 0;
int eoff = 0;
int clen = (comment != null) ? comment.length : 0; int clen = (comment != null) ? comment.length : 0;
if (csize >= ZIP64_MINVAL) { if (csize >= ZIP64_MINVAL) {
csize0 = ZIP64_MINVAL; csize0 = ZIP64_MINVAL;
@ -1936,14 +1937,24 @@ public class ZipFileSystem extends FileSystem {
locoff0 = ZIP64_MINVAL; locoff0 = ZIP64_MINVAL;
elen64 += 8; // offset(8) elen64 += 8; // offset(8)
} }
if (elen64 != 0) if (elen64 != 0) {
elen64 += 4; // header and data sz 4 bytes elen64 += 4; // header and data sz 4 bytes
}
if (atime != -1) { while (eoff + 4 < elen) {
if (isWindows) // use NTFS int tag = SH(extra, eoff);
int sz = SH(extra, eoff + 2);
if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
foundExtraTime = true;
}
eoff += (4 + sz);
}
if (!foundExtraTime) {
if (isWindows) { // use NTFS
elenNTFS = 36; // total 36 bytes elenNTFS = 36; // total 36 bytes
else // Extended Timestamp otherwise } else { // Extended Timestamp otherwise
elenEXTT = 9; // only mtime in cen elenEXTT = 9; // only mtime in cen
}
} }
writeInt(os, CENSIG); // CEN header signature writeInt(os, CENSIG); // CEN header signature
if (elen64 != 0) { if (elen64 != 0) {
@ -2092,11 +2103,13 @@ public class ZipFileSystem extends FileSystem {
{ {
writeInt(os, LOCSIG); // LOC header signature writeInt(os, LOCSIG); // LOC header signature
int version = version(); int version = version();
int nlen = (name != null) ? name.length : 0; int nlen = (name != null) ? name.length : 0;
int elen = (extra != null) ? extra.length : 0; int elen = (extra != null) ? extra.length : 0;
boolean foundExtraTime = false; // if extra timestamp present
int eoff = 0;
int elen64 = 0; int elen64 = 0;
int elenEXTT = 0; int elenEXTT = 0;
int elenNTFS = 0;
if ((flag & FLAG_DATADESCR) != 0) { if ((flag & FLAG_DATADESCR) != 0) {
writeShort(os, version()); // version needed to extract writeShort(os, version()); // version needed to extract
writeShort(os, flag); // general purpose bit flag writeShort(os, flag); // general purpose bit flag
@ -2128,14 +2141,27 @@ public class ZipFileSystem extends FileSystem {
writeInt(os, size); // uncompressed size writeInt(os, size); // uncompressed size
} }
} }
if (atime != -1 && !isWindows) { // on unix use "ext time" while (eoff + 4 < elen) {
if (ctime == -1) int tag = SH(extra, eoff);
elenEXTT = 13; int sz = SH(extra, eoff + 2);
else if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
elenEXTT = 17; foundExtraTime = true;
}
eoff += (4 + sz);
}
if (!foundExtraTime) {
if (isWindows) {
elenNTFS = 36; // NTFS, total 36 bytes
} else { // on unix use "ext time"
elenEXTT = 9;
if (atime != -1)
elenEXTT += 4;
if (ctime != -1)
elenEXTT += 4;
}
} }
writeShort(os, name.length); writeShort(os, name.length);
writeShort(os, elen + elen64 + elenEXTT); writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
writeBytes(os, name); writeBytes(os, name);
if (elen64 != 0) { if (elen64 != 0) {
writeShort(os, EXTID_ZIP64); writeShort(os, EXTID_ZIP64);
@ -2143,15 +2169,28 @@ public class ZipFileSystem extends FileSystem {
writeLong(os, size); writeLong(os, size);
writeLong(os, csize); writeLong(os, csize);
} }
if (elenNTFS != 0) {
writeShort(os, EXTID_NTFS);
writeShort(os, elenNTFS - 4);
writeInt(os, 0); // reserved
writeShort(os, 0x0001); // NTFS attr tag
writeShort(os, 24);
writeLong(os, javaToWinTime(mtime));
writeLong(os, javaToWinTime(atime));
writeLong(os, javaToWinTime(ctime));
}
if (elenEXTT != 0) { if (elenEXTT != 0) {
writeShort(os, EXTID_EXTT); writeShort(os, EXTID_EXTT);
writeShort(os, elenEXTT - 4);// size for the folowing data block writeShort(os, elenEXTT - 4);// size for the folowing data block
if (ctime == -1) int fbyte = 0x1;
os.write(0x3); // mtime and atime if (atime != -1) // mtime and atime
else fbyte |= 0x2;
os.write(0x7); // mtime, atime and ctime if (ctime != -1) // mtime, atime and ctime
fbyte |= 0x4;
os.write(fbyte); // flags byte
writeInt(os, javaToUnixTime(mtime)); writeInt(os, javaToUnixTime(mtime));
writeInt(os, javaToUnixTime(atime)); if (atime != -1)
writeInt(os, javaToUnixTime(atime));
if (ctime != -1) if (ctime != -1)
writeInt(os, javaToUnixTime(ctime)); writeInt(os, javaToUnixTime(ctime));
} }

View File

@ -214,7 +214,7 @@ public class ZipInfo {
winToJavaTime(LL(extra, off + 24))); winToJavaTime(LL(extra, off + 24)));
break; break;
case EXTID_EXTT: case EXTID_EXTT:
print(" ->Inof-ZIP Extended Timestamp: flag=%x%n",extra[off]); print(" ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]);
pos = off + 1 ; pos = off + 1 ;
while (pos + 4 <= off + sz) { while (pos + 4 <= off + sz) {
print(" *%tc%n", print(" *%tc%n",
@ -223,6 +223,7 @@ public class ZipInfo {
} }
break; break;
default: default:
print(" ->[tag=%x, size=%d]%n", tag, sz);
} }
off += sz; off += sz;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,7 +49,8 @@ enum {
JMM_VERSION_1_1 = 0x20010100, // JDK 6 JMM_VERSION_1_1 = 0x20010100, // JDK 6
JMM_VERSION_1_2 = 0x20010200, // JDK 7 JMM_VERSION_1_2 = 0x20010200, // JDK 7
JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
JMM_VERSION = 0x20010202 JMM_VERSION_1_2_2 = 0x20010202,
JMM_VERSION = 0x20010203
}; };
typedef struct { typedef struct {
@ -62,7 +63,8 @@ typedef struct {
unsigned int isObjectMonitorUsageSupported : 1; unsigned int isObjectMonitorUsageSupported : 1;
unsigned int isSynchronizerUsageSupported : 1; unsigned int isSynchronizerUsageSupported : 1;
unsigned int isThreadAllocatedMemorySupported : 1; unsigned int isThreadAllocatedMemorySupported : 1;
unsigned int : 23; unsigned int isRemoteDiagnosticCommandsSupported : 1;
unsigned int : 22;
} jmmOptionalSupport; } jmmOptionalSupport;
typedef enum { typedef enum {
@ -190,21 +192,27 @@ typedef struct {
} jmmGCStat; } jmmGCStat;
typedef struct { typedef struct {
const char* name; const char* name; /* Name of the diagnostic command */
const char* description; const char* description; /* Short description */
const char* impact; const char* impact; /* Impact on the JVM */
int num_arguments; const char* permission_class; /* Class name of the required permission if any */
jboolean enabled; const char* permission_name; /* Permission name of the required permission if any */
const char* permission_action; /* Action name of the required permission if any*/
int num_arguments; /* Number of supported options or arguments */
jboolean enabled; /* True if the diagnostic command can be invoked, false otherwise*/
} dcmdInfo; } dcmdInfo;
typedef struct { typedef struct {
const char* name; const char* name; /* Option/Argument name*/
const char* description; const char* description; /* Short description */
const char* type; const char* type; /* Type: STRING, BOOLEAN, etc. */
const char* default_string; const char* default_string; /* Default value in a parsable string */
jboolean mandatory; jboolean mandatory; /* True if the option/argument is mandatory */
jboolean option; jboolean option; /* True if it is an option, false if it is an argument */
int position; /* (see diagnosticFramework.hpp for option/argument definitions) */
jboolean multiple; /* True is the option can be specified several time */
int position; /* Expected position for this argument (this field is */
/* meaningless for options) */
} dcmdArgInfo; } dcmdArgInfo;
typedef struct jmmInterface_1_ { typedef struct jmmInterface_1_ {
@ -327,6 +335,9 @@ typedef struct jmmInterface_1_ {
jstring (JNICALL *ExecuteDiagnosticCommand) jstring (JNICALL *ExecuteDiagnosticCommand)
(JNIEnv *env, (JNIEnv *env,
jstring command); jstring command);
void (JNICALL *SetDiagnosticFrameworkNotificationEnabled)
(JNIEnv *env,
jboolean enabled);
} JmmInterface; } JmmInterface;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,169 @@
/*
* 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.
*/
#include <jni.h>
#include "management.h"
#include "sun_management_DiagnosticCommandImpl.h"
JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
(JNIEnv *env, jobject dummy, jboolean enabled) {
if(jmm_version > JMM_VERSION_1_2_2) {
jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
} else {
JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
"JMX interface to diagnostic framework notifications is not supported by this VM");
}
}
JNIEXPORT jobjectArray JNICALL
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands
(JNIEnv *env, jobject dummy)
{
return jmm_interface->GetDiagnosticCommands(env);
}
jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
int num_arg) {
int i;
jobject obj;
jobjectArray result;
dcmdArgInfo* dcmd_arg_info_array;
jclass dcmdArgInfoCls;
jclass arraysCls;
jmethodID mid;
jobject resultList;
dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
if (dcmd_arg_info_array == NULL) {
return NULL;
}
jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
dcmd_arg_info_array);
dcmdArgInfoCls = (*env)->FindClass(env,
"sun/management/DiagnosticCommandArgumentInfo");
result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
if (result == NULL) {
free(dcmd_arg_info_array);
return NULL;
}
for (i=0; i<num_arg; i++) {
obj = JNU_NewObjectByName(env,
"sun/management/DiagnosticCommandArgumentInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V",
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
(*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
dcmd_arg_info_array[i].default_string == NULL ? NULL:
(*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
dcmd_arg_info_array[i].mandatory,
dcmd_arg_info_array[i].option,
dcmd_arg_info_array[i].multiple,
dcmd_arg_info_array[i].position);
if (obj == NULL) {
free(dcmd_arg_info_array);
return NULL;
}
(*env)->SetObjectArrayElement(env, result, i, obj);
}
free(dcmd_arg_info_array);
arraysCls = (*env)->FindClass(env, "java/util/Arrays");
mid = (*env)->GetStaticMethodID(env, arraysCls,
"asList", "([Ljava/lang/Object;)Ljava/util/List;");
resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
return resultList;
}
/* Throws IllegalArgumentException if at least one of the diagnostic command
* passed in argument is not supported by the JVM
*/
JNIEXPORT jobjectArray JNICALL
Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo
(JNIEnv *env, jobject dummy, jobjectArray commands)
{
int i;
jclass dcmdInfoCls;
jobject result;
jobjectArray args;
jobject obj;
jmmOptionalSupport mos;
jint ret = jmm_interface->GetOptionalSupport(env, &mos);
jsize num_commands;
dcmdInfo* dcmd_info_array;
if (commands == NULL) {
JNU_ThrowNullPointerException(env, "Invalid String Array");
return NULL;
}
num_commands = (*env)->GetArrayLength(env, commands);
dcmd_info_array = (dcmdInfo*) malloc(num_commands *
sizeof(dcmdInfo));
if (dcmd_info_array == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
}
jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
dcmdInfoCls = (*env)->FindClass(env,
"sun/management/DiagnosticCommandInfo");
result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
if (result == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
for (i=0; i<num_commands; i++) {
args = getDiagnosticCommandArgumentInfoArray(env,
(*env)->GetObjectArrayElement(env,commands,i),
dcmd_info_array[i].num_arguments);
if (args == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
obj = JNU_NewObjectByName(env,
"sun/management/DiagnosticCommandInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
(*env)->NewStringUTF(env,dcmd_info_array[i].name),
(*env)->NewStringUTF(env,dcmd_info_array[i].description),
(*env)->NewStringUTF(env,dcmd_info_array[i].impact),
dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
dcmd_info_array[i].enabled,
args);
if (obj == NULL) {
free(dcmd_info_array);
JNU_ThrowOutOfMemoryError(env, 0);
}
(*env)->SetObjectArrayElement(env, result, i, obj);
}
free(dcmd_info_array);
return result;
}
/* Throws IllegalArgumentException if the diagnostic command
* passed in argument is not supported by the JVM
*/
JNIEXPORT jstring JNICALL
Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand
(JNIEnv *env, jobject dummy, jstring command) {
return jmm_interface->ExecuteDiagnosticCommand(env, command);
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2011, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@
*/ */
#include <jni.h> #include <jni.h>
#include <stdlib.h>
#include "jvm.h" #include "jvm.h"
#include "management.h" #include "management.h"
#include "sun_management_VMManagementImpl.h" #include "sun_management_VMManagementImpl.h"
@ -96,6 +97,9 @@ Java_sun_management_VMManagementImpl_initOptionalSupportFields
value = mos.isThreadAllocatedMemorySupported; value = mos.isThreadAllocatedMemorySupported;
setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value); setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
value = mos.isRemoteDiagnosticCommandsSupported;
setStaticBooleanField(env, cls, "remoteDiagnosticCommandsSupport", value);
if ((jmm_version > JMM_VERSION_1_2) || if ((jmm_version > JMM_VERSION_1_2) ||
(jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) { (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE); setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);

View File

@ -649,9 +649,9 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
&& (dmpath == NULL) /* data model specific variables not set */ && (dmpath == NULL) /* data model specific variables not set */
#endif /* __solaris__ */ #endif /* __solaris__ */
) { ) {
JLI_MemFree(newargv);
JLI_MemFree(new_runpath);
return; return;
} }
} }
@ -935,7 +935,7 @@ SetExecname(char **argv)
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];
int len = readlink(self, buf, PATH_MAX); int len = readlink(self, buf, PATH_MAX);
if (len >= 0) { if (len >= 0) {
buf[len] = '\0'; /* readlink doesn't nul terminate */ buf[len] = '\0'; /* readlink(2) doesn't NUL terminate */
exec_path = JLI_StringDup(buf); exec_path = JLI_StringDup(buf);
} }
} }

View File

@ -658,9 +658,9 @@ jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
if (ia2Obj) { if (ia2Obj) {
setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
(*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
(*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
} }
} }
(*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask);
(*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj);
} }
} }
@ -887,15 +887,12 @@ netif *addif(JNIEnv *env, int sock, const char * if_name,
addrP->mask = prefix; addrP->mask = prefix;
addrP->next = 0; addrP->next = 0;
if (family == AF_INET) { if (family == AF_INET) {
/* // Deal with broadcast addr & subnet mask
* Deal with broadcast addr & subnet mask
*/
struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size); struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
addrP->brdcast = getBroadcast(env, sock, name, brdcast_to ); addrP->brdcast = getBroadcast(env, sock, name, brdcast_to );
if (addrP->brdcast && (mask = getSubnet(env, sock, name)) != -1) { if ((mask = getSubnet(env, sock, name)) != -1)
addrP->mask = mask; addrP->mask = mask;
}
} }
/** /**

View File

@ -185,7 +185,6 @@ extern char *XSetIMValues(
); );
#endif #endif
#ifdef XAWT_HACK
/* /*
* This function is stolen from /src/solaris/hpi/src/system_md.c * This function is stolen from /src/solaris/hpi/src/system_md.c
* It is used in setting the time in Java-level InputEvents * It is used in setting the time in Java-level InputEvents
@ -197,7 +196,6 @@ awt_util_nowMillisUTC()
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000); return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
} }
#endif /* XAWT_HACK */
/* /*
* Converts the wchar_t string to a multi-byte string calling wcstombs(). A * Converts the wchar_t string to a multi-byte string calling wcstombs(). A
@ -546,11 +544,7 @@ awt_x11inputmethod_lookupString(XKeyPressedEvent *event, KeySym *keysymp)
"dispatchCommittedText", "dispatchCommittedText",
"(Ljava/lang/String;J)V", "(Ljava/lang/String;J)V",
javastr, javastr,
#ifndef XAWT_HACK
awt_util_nowMillisUTC_offset(event->time));
#else
event->time); event->time);
#endif
} }
break; break;

View File

@ -48,7 +48,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.spi.CalendarDataProvider; import java.util.spi.CalendarDataProvider;
import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider; import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider; import java.util.spi.LocaleNameProvider;
import sun.util.spi.CalendarProvider; import sun.util.spi.CalendarProvider;
@ -364,32 +363,6 @@ public class HostLocaleProviderAdapterImpl {
}; };
} }
public static CalendarNameProvider getCalendarNameProvider() {
return new CalendarNameProvider() {
@Override
public Locale[] getAvailableLocales() {
return getSupportedCalendarLocales();
}
@Override
public boolean isSupportedLocale(Locale locale) {
return isSupportedCalendarLocale(locale);
}
@Override
public String getDisplayName(String calType, int field, int value,
int style, Locale locale) {
return null;
}
@Override
public Map<String, Integer> getDisplayNames(String calType,
int field, int style, Locale locale) {
return null;
}
};
}
public static CalendarProvider getCalendarProvider() { public static CalendarProvider getCalendarProvider() {
return new CalendarProvider() { return new CalendarProvider() {
@Override @Override

View File

@ -256,14 +256,14 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketRece
packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID); packetBuffer = (*env)->GetObjectField(env, dpObj, dp_bufID);
packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID); packetBufferOffset = (*env)->GetIntField(env, dpObj, dp_offsetID);
packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID); packetBufferLen = (*env)->GetIntField(env, dpObj, dp_bufLengthID);
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
if (packetBufferLen > MAX_BUFFER_LEN) { if (packetBufferLen > MAX_BUFFER_LEN) {
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)
* the max size of an IP packet. Anything bigger is truncated anyway.
*/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
fullPacket = (char *)malloc(packetBufferLen); fullPacket = (char *)malloc(packetBufferLen);
if (!fullPacket) { if (!fullPacket) {
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");

View File

@ -145,7 +145,7 @@ static int getFD1(JNIEnv *env, jobject this) {
/* /*
* This function returns JNI_TRUE if the datagram size exceeds the underlying * This function returns JNI_TRUE if the datagram size exceeds the underlying
* provider's ability to send to the target address. The following OS * provider's ability to send to the target address. The following OS
* oddies have been observed :- * oddities have been observed :-
* *
* 1. On Windows 95/98 if we try to send a datagram > 12k to an application * 1. On Windows 95/98 if we try to send a datagram > 12k to an application
* on the same machine then the send will fail silently. * on the same machine then the send will fail silently.
@ -218,7 +218,7 @@ jboolean exceedSizeLimit(JNIEnv *env, jint fd, jint addr, jint size)
/* /*
* Step 3: On Windows 95/98 then enumerate the IP addresses on * Step 3: On Windows 95/98 then enumerate the IP addresses on
* this machine. This is necesary because we need to check if the * this machine. This is neccesary because we need to check if the
* datagram is being sent to an application on the same machine. * datagram is being sent to an application on the same machine.
*/ */
if (is95or98) { if (is95or98) {
@ -565,8 +565,8 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_connect0(JNIEnv *env, jobject thi
if (xp_or_later) { if (xp_or_later) {
/* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which /* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
* returns connection reset errors un connected UDP sockets (as well * returns connection reset errors on connected UDP sockets (as well
* as connected sockets. The solution is to only enable this feature * as connected sockets). The solution is to only enable this feature
* when the socket is connected * when the socket is connected
*/ */
DWORD x1, x2; /* ignored result codes */ DWORD x1, x2; /* ignored result codes */
@ -690,6 +690,12 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID); packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
/* Note: the buffer needn't be greater than 65,536 (0xFFFF)...
* the maximum size of an IP packet. Anything bigger is truncated anyway.
*/
if (packetBufferLen > MAX_PACKET_LEN) {
packetBufferLen = MAX_PACKET_LEN;
}
if (connected) { if (connected) {
addrp = 0; /* arg to JVM_Sendto () null in this case */ addrp = 0; /* arg to JVM_Sendto () null in this case */
@ -728,7 +734,7 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
} }
/* When JNI-ifying the JDK's IO routines, we turned /* When JNI-ifying the JDK's IO routines, we turned
* read's and write's of byte arrays of size greater * reads and writes of byte arrays of size greater
* than 2048 bytes into several operations of size 2048. * than 2048 bytes into several operations of size 2048.
* This saves a malloc()/memcpy()/free() for big * This saves a malloc()/memcpy()/free() for big
* buffers. This is OK for file IO and TCP, but that * buffers. This is OK for file IO and TCP, but that

View File

@ -122,9 +122,6 @@
# jdk_lang # jdk_lang
# 8009615
java/lang/instrument/IsModifiableClassAgent.java generic-all
# 6944188 # 6944188
java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all
@ -137,6 +134,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all
# 8008200 # 8008200
java/lang/Class/asSubclass/BasicUnit.java generic-all java/lang/Class/asSubclass/BasicUnit.java generic-all
# 8015780
java/lang/reflect/Method/GenericStringTest.java generic-all
############################################################################ ############################################################################
# jdk_management # jdk_management
@ -199,12 +199,6 @@ java/net/MulticastSocket/Test.java macosx-all
# 7143960 # 7143960
java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all
# 8014720
java/net/ResponseCache/B6181108.java generic-all
# 8014723
sun/misc/URLClassPath/ClassnameCharTest.java generic-all
# 8014719 # 8014719
sun/net/www/http/HttpClient/ProxyTest.java generic-all sun/net/www/http/HttpClient/ProxyTest.java generic-all
@ -236,9 +230,6 @@ java/nio/channels/DatagramChannel/ChangingAddress.java macosx-all
# 7132677 # 7132677
java/nio/channels/Selector/OutOfBand.java macosx-all java/nio/channels/Selector/OutOfBand.java macosx-all
# 8003895
java/nio/channels/AsynchronousChannelGroup/Unbounded.java windows-amd64
############################################################################ ############################################################################
# jdk_rmi # jdk_rmi
@ -277,6 +268,13 @@ sun/security/pkcs11/ec/ReadCertificates.java solaris-all
sun/security/pkcs11/ec/ReadPKCS12.java solaris-all sun/security/pkcs11/ec/ReadPKCS12.java solaris-all
sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all
# 8005247
sun/security/pkcs11/ec/TestECDSA.java solaris-all
# 8009438
sun/security/pkcs11/Secmod/AddPrivateKey.java linux-all
sun/security/pkcs11/Secmod/TrustAnchors.java linux-all
# 7041639, Solaris DSA keypair generation bug (Note: jdk_util also affected) # 7041639, Solaris DSA keypair generation bug (Note: jdk_util also affected)
java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all
sun/security/tools/jarsigner/onlymanifest.sh solaris-all sun/security/tools/jarsigner/onlymanifest.sh solaris-all
@ -331,6 +329,8 @@ sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
# Tests take too long, on sparcs see 7143279 # Tests take too long, on sparcs see 7143279
tools/pack200/CommandLineTests.java solaris-all, macosx-all tools/pack200/CommandLineTests.java solaris-all, macosx-all
tools/pack200/Pack200Test.java solaris-all, macosx-all tools/pack200/Pack200Test.java solaris-all, macosx-all
# 8015666
tools/pack200/TimeStamp.java generic-all
# 8007410 # 8007410
tools/launcher/FXLauncherTest.java linux-all tools/launcher/FXLauncherTest.java linux-all

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2012, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,8 +23,8 @@
/** /**
* @test * @test
* @bug 4893959 * @bug 4893959 8013069
* @summary basic test for HmacPBESHA1 * @summary basic test for PBE MAC algorithms.
* @author Valerie Peng * @author Valerie Peng
*/ */
import java.io.PrintStream; import java.io.PrintStream;
@ -68,8 +68,9 @@ public class HmacPBESHA1 {
} }
Mac mac = Mac.getInstance(algo, PROVIDER); Mac mac = Mac.getInstance(algo, PROVIDER);
byte[] plainText = new byte[30]; byte[] plainText = new byte[30];
PBEParameterSpec spec =
mac.init(key); new PBEParameterSpec("saltValue".getBytes(), 250);
mac.init(key, spec);
mac.update(plainText); mac.update(plainText);
byte[] value1 = mac.doFinal(); byte[] value1 = mac.doFinal();
if (value1.length != length) { if (value1.length != length) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,12 +23,13 @@
/* /*
* @test * @test
* @bug 7087021 * @bug 7087021 8013069
* @summary MacClone * @summary Clone tests for all MAC algorithms.
* @author Jan Luehe * @author Jan Luehe
*/ */
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*; import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.*;
public class MacClone { public class MacClone {
@ -39,18 +40,23 @@ public class MacClone {
KeyGenerator kgen = KeyGenerator.getInstance("DES"); KeyGenerator kgen = KeyGenerator.getInstance("DES");
SecretKey skey = kgen.generateKey(); SecretKey skey = kgen.generateKey();
for (String algo : algos) { for (String algo : algos) {
doTest(algo, skey); doTest(algo, skey, null);
} }
String[] algos2 = { "HmacPBESHA1" }; String[] algos2 = { "HmacPBESHA1", "PBEWithHmacSHA1",
"PBEWithHmacSHA224", "PBEWithHmacSHA256",
"PBEWithHmacSHA384", "PBEWithHmacSHA512" };
skey = new SecretKeySpec("whatever".getBytes(), "PBE"); skey = new SecretKeySpec("whatever".getBytes(), "PBE");
PBEParameterSpec params =
new PBEParameterSpec("1234567890".getBytes(), 500);
for (String algo : algos2) { for (String algo : algos2) {
doTest(algo, skey); doTest(algo, skey, params);
} }
System.out.println("Test Passed"); System.out.println("Test Passed");
} }
private static void doTest(String algo, SecretKey skey) throws Exception { private static void doTest(String algo, SecretKey skey,
AlgorithmParameterSpec params) throws Exception {
// //
// Clone an uninitialized Mac object // Clone an uninitialized Mac object
// //
@ -72,7 +78,7 @@ public class MacClone {
// Clone an initialized Mac object // Clone an initialized Mac object
// //
mac = Mac.getInstance(algo, "SunJCE"); mac = Mac.getInstance(algo, "SunJCE");
mac.init(skey); mac.init(skey, params);
macClone = (Mac)mac.clone(); macClone = (Mac)mac.clone();
System.out.println(macClone.getProvider().toString()); System.out.println(macClone.getProvider().toString());
System.out.println(macClone.getAlgorithm()); System.out.println(macClone.getAlgorithm());

View File

@ -0,0 +1,420 @@
/*
* 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 8014618
* @summary Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
* @author Pasi Eronen
*/
import java.io.*;
import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
import com.sun.crypto.provider.SunJCE;
/**
* Test that leading zeroes are stripped in TlsPremasterSecret case,
* but are left as-is in other cases.
*
* We use pre-generated keypairs, since with randomly generated keypairs,
* a leading zero happens only (roughly) 1 out of 256 cases.
*/
public class TestLeadingZeroes {
private static final String SUNJCE = "SunJCE";
private TestLeadingZeroes() {}
public static void main(String argv[]) throws Exception {
// Add JCE to the list of providers
SunJCE jce = new SunJCE();
Security.addProvider(jce);
TestLeadingZeroes keyAgree = new TestLeadingZeroes();
keyAgree.run();
System.out.println("Test Passed");
}
private void run() throws Exception {
// decode pre-generated keypairs
KeyFactory kfac = KeyFactory.getInstance("DH");
PublicKey alicePubKey =
kfac.generatePublic(new X509EncodedKeySpec(alicePubKeyEnc));
PublicKey bobPubKey =
kfac.generatePublic(new X509EncodedKeySpec(bobPubKeyEnc));
PrivateKey alicePrivKey =
kfac.generatePrivate(new PKCS8EncodedKeySpec(alicePrivKeyEnc));
PrivateKey bobPrivKey =
kfac.generatePrivate(new PKCS8EncodedKeySpec(bobPrivKeyEnc));
// generate normal shared secret
KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH", SUNJCE);
aliceKeyAgree.init(alicePrivKey);
aliceKeyAgree.doPhase(bobPubKey, true);
byte[] sharedSecret = aliceKeyAgree.generateSecret();
System.out.println("shared secret:\n" + toHexString(sharedSecret));
// verify that leading zero is present
if (sharedSecret.length != 128) {
throw new Exception("Unexpected shared secret length");
}
if (sharedSecret[0] != 0) {
throw new Exception("First byte is not zero as expected");
}
// now, test TLS premaster secret
aliceKeyAgree.init(alicePrivKey);
aliceKeyAgree.doPhase(bobPubKey, true);
byte[] tlsPremasterSecret =
aliceKeyAgree.generateSecret("TlsPremasterSecret").getEncoded();
System.out.println(
"tls premaster secret:\n" + toHexString(tlsPremasterSecret));
// check that leading zero has been stripped
if (tlsPremasterSecret.length != 127) {
throw new Exception("Unexpected TLS premaster secret length");
}
if (tlsPremasterSecret[0] == 0) {
throw new Exception("First byte is zero");
}
for (int i = 0; i < tlsPremasterSecret.length; i++) {
if (tlsPremasterSecret[i] != sharedSecret[i+1]) {
throw new Exception("Shared secrets differ");
}
}
}
/*
* Converts a byte to hex digit and writes to the supplied buffer
*/
private void byte2hex(byte b, StringBuffer buf) {
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
/*
* Converts a byte array to hex string
*/
private String toHexString(byte[] block) {
StringBuffer buf = new StringBuffer();
int len = block.length;
for (int i = 0; i < len; i++) {
byte2hex(block[i], buf);
if (i < len-1) {
buf.append(":");
}
}
return buf.toString();
}
private static final byte alicePubKeyEnc[] = {
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x24,
(byte)0x30, (byte)0x81, (byte)0x99, (byte)0x06,
(byte)0x09, (byte)0x2A, (byte)0x86, (byte)0x48,
(byte)0x86, (byte)0xF7, (byte)0x0D, (byte)0x01,
(byte)0x03, (byte)0x01, (byte)0x30, (byte)0x81,
(byte)0x8B, (byte)0x02, (byte)0x81, (byte)0x81,
(byte)0x00, (byte)0xF4, (byte)0x88, (byte)0xFD,
(byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB,
(byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D,
(byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36,
(byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38,
(byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F,
(byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C,
(byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E,
(byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23,
(byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5,
(byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E,
(byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8,
(byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34,
(byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57,
(byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18,
(byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21,
(byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF,
(byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29,
(byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D,
(byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A,
(byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4,
(byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07,
(byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95,
(byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F,
(byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50,
(byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3,
(byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4,
(byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C,
(byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B,
(byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA,
(byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3,
(byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78,
(byte)0xC7, (byte)0x02, (byte)0x01, (byte)0x02,
(byte)0x02, (byte)0x02, (byte)0x02, (byte)0x00,
(byte)0x03, (byte)0x81, (byte)0x85, (byte)0x00,
(byte)0x02, (byte)0x81, (byte)0x81, (byte)0x00,
(byte)0xEE, (byte)0xD6, (byte)0xB1, (byte)0xA3,
(byte)0xB4, (byte)0x78, (byte)0x2B, (byte)0x35,
(byte)0xEF, (byte)0xCD, (byte)0x17, (byte)0x86,
(byte)0x63, (byte)0x2B, (byte)0x97, (byte)0x0E,
(byte)0x7A, (byte)0xD1, (byte)0xFF, (byte)0x7A,
(byte)0xEB, (byte)0x57, (byte)0x61, (byte)0xA1,
(byte)0xF7, (byte)0x90, (byte)0x11, (byte)0xA7,
(byte)0x79, (byte)0x28, (byte)0x69, (byte)0xBA,
(byte)0xA7, (byte)0xB2, (byte)0x37, (byte)0x17,
(byte)0xAE, (byte)0x3C, (byte)0x92, (byte)0x89,
(byte)0x88, (byte)0xE5, (byte)0x7E, (byte)0x8E,
(byte)0xF0, (byte)0x24, (byte)0xD0, (byte)0xE1,
(byte)0xC4, (byte)0xB0, (byte)0x26, (byte)0x5A,
(byte)0x1E, (byte)0xBD, (byte)0xA0, (byte)0xCF,
(byte)0x3E, (byte)0x97, (byte)0x2A, (byte)0x13,
(byte)0x92, (byte)0x3B, (byte)0x39, (byte)0xD0,
(byte)0x1D, (byte)0xA3, (byte)0x6B, (byte)0x3E,
(byte)0xC2, (byte)0xBB, (byte)0x14, (byte)0xB6,
(byte)0xE2, (byte)0x4C, (byte)0x0E, (byte)0x5B,
(byte)0x4B, (byte)0xA4, (byte)0x9D, (byte)0xA6,
(byte)0x21, (byte)0xB0, (byte)0xF9, (byte)0xDE,
(byte)0x55, (byte)0xAE, (byte)0x5C, (byte)0x29,
(byte)0x0E, (byte)0xC1, (byte)0xFC, (byte)0xBA,
(byte)0x51, (byte)0xD3, (byte)0xB6, (byte)0x6D,
(byte)0x75, (byte)0x72, (byte)0xDF, (byte)0x43,
(byte)0xAB, (byte)0x94, (byte)0x21, (byte)0x6E,
(byte)0x0C, (byte)0xD1, (byte)0x93, (byte)0x54,
(byte)0x56, (byte)0x7D, (byte)0x4B, (byte)0x90,
(byte)0xF1, (byte)0x94, (byte)0x45, (byte)0xD4,
(byte)0x2A, (byte)0x71, (byte)0xA1, (byte)0xB8,
(byte)0xDD, (byte)0xAA, (byte)0x05, (byte)0xF0,
(byte)0x27, (byte)0x37, (byte)0xBD, (byte)0x44
};
private static final byte alicePrivKeyEnc[] = {
(byte)0x30, (byte)0x81, (byte)0xE3, (byte)0x02,
(byte)0x01, (byte)0x00, (byte)0x30, (byte)0x81,
(byte)0x99, (byte)0x06, (byte)0x09, (byte)0x2A,
(byte)0x86, (byte)0x48, (byte)0x86, (byte)0xF7,
(byte)0x0D, (byte)0x01, (byte)0x03, (byte)0x01,
(byte)0x30, (byte)0x81, (byte)0x8B, (byte)0x02,
(byte)0x81, (byte)0x81, (byte)0x00, (byte)0xF4,
(byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E,
(byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20,
(byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91,
(byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33,
(byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45,
(byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88,
(byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B,
(byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3,
(byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43,
(byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18,
(byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55,
(byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38,
(byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C,
(byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3,
(byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE,
(byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5,
(byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1,
(byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18,
(byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84,
(byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6,
(byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19,
(byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A,
(byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9,
(byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0,
(byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02,
(byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D,
(byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41,
(byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD,
(byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19,
(byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2,
(byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9,
(byte)0x2F, (byte)0x78, (byte)0xC7, (byte)0x02,
(byte)0x01, (byte)0x02, (byte)0x02, (byte)0x02,
(byte)0x02, (byte)0x00, (byte)0x04, (byte)0x42,
(byte)0x02, (byte)0x40, (byte)0x36, (byte)0x4D,
(byte)0xD0, (byte)0x58, (byte)0x64, (byte)0x91,
(byte)0x78, (byte)0xA2, (byte)0x4B, (byte)0x79,
(byte)0x46, (byte)0xFE, (byte)0xC9, (byte)0xD9,
(byte)0xCA, (byte)0x5C, (byte)0xF9, (byte)0xFD,
(byte)0x6C, (byte)0x5D, (byte)0x76, (byte)0x3A,
(byte)0x41, (byte)0x6D, (byte)0x44, (byte)0x62,
(byte)0x75, (byte)0x93, (byte)0x81, (byte)0x93,
(byte)0x00, (byte)0x4C, (byte)0xB1, (byte)0xD8,
(byte)0x7D, (byte)0x9D, (byte)0xF3, (byte)0x16,
(byte)0x2C, (byte)0x6C, (byte)0x9F, (byte)0x7A,
(byte)0x84, (byte)0xA3, (byte)0x7A, (byte)0xC1,
(byte)0x4F, (byte)0x60, (byte)0xE3, (byte)0xB5,
(byte)0x86, (byte)0x28, (byte)0x08, (byte)0x4D,
(byte)0x94, (byte)0xB6, (byte)0x04, (byte)0x0D,
(byte)0xAC, (byte)0xBD, (byte)0x1F, (byte)0x42,
(byte)0x8F, (byte)0x1B
};
private static final byte bobPubKeyEnc[] = {
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x23,
(byte)0x30, (byte)0x81, (byte)0x99, (byte)0x06,
(byte)0x09, (byte)0x2A, (byte)0x86, (byte)0x48,
(byte)0x86, (byte)0xF7, (byte)0x0D, (byte)0x01,
(byte)0x03, (byte)0x01, (byte)0x30, (byte)0x81,
(byte)0x8B, (byte)0x02, (byte)0x81, (byte)0x81,
(byte)0x00, (byte)0xF4, (byte)0x88, (byte)0xFD,
(byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB,
(byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D,
(byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36,
(byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38,
(byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F,
(byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C,
(byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E,
(byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23,
(byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5,
(byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E,
(byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8,
(byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34,
(byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57,
(byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18,
(byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21,
(byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF,
(byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29,
(byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D,
(byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A,
(byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4,
(byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07,
(byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95,
(byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F,
(byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50,
(byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3,
(byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4,
(byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C,
(byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B,
(byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA,
(byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3,
(byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78,
(byte)0xC7, (byte)0x02, (byte)0x01, (byte)0x02,
(byte)0x02, (byte)0x02, (byte)0x02, (byte)0x00,
(byte)0x03, (byte)0x81, (byte)0x84, (byte)0x00,
(byte)0x02, (byte)0x81, (byte)0x80, (byte)0x2C,
(byte)0x40, (byte)0xFA, (byte)0xF6, (byte)0xA6,
(byte)0xF8, (byte)0xAC, (byte)0xC2, (byte)0x4F,
(byte)0xCD, (byte)0xC7, (byte)0x37, (byte)0x93,
(byte)0xE5, (byte)0xE4, (byte)0x5E, (byte)0x18,
(byte)0x14, (byte)0xE6, (byte)0x50, (byte)0xDA,
(byte)0x55, (byte)0x38, (byte)0x5D, (byte)0x24,
(byte)0xF5, (byte)0x42, (byte)0x68, (byte)0x5F,
(byte)0xF5, (byte)0x15, (byte)0xC8, (byte)0x9B,
(byte)0x5D, (byte)0x06, (byte)0x3D, (byte)0xE1,
(byte)0x52, (byte)0x2F, (byte)0x98, (byte)0xFF,
(byte)0x37, (byte)0xBB, (byte)0x75, (byte)0x48,
(byte)0x48, (byte)0xE9, (byte)0x65, (byte)0x84,
(byte)0x37, (byte)0xBB, (byte)0xB3, (byte)0xE9,
(byte)0x36, (byte)0x01, (byte)0xB4, (byte)0x6A,
(byte)0x1C, (byte)0xB2, (byte)0x11, (byte)0x82,
(byte)0xCE, (byte)0x3D, (byte)0x65, (byte)0xE5,
(byte)0x3C, (byte)0x89, (byte)0xE9, (byte)0x52,
(byte)0x19, (byte)0xBD, (byte)0x58, (byte)0xF6,
(byte)0xA2, (byte)0x03, (byte)0xA8, (byte)0xB2,
(byte)0xA5, (byte)0xDB, (byte)0xEB, (byte)0xF5,
(byte)0x94, (byte)0xF9, (byte)0x46, (byte)0xBE,
(byte)0x45, (byte)0x4C, (byte)0x65, (byte)0xD2,
(byte)0xD1, (byte)0xCF, (byte)0xFF, (byte)0xFF,
(byte)0xFA, (byte)0x38, (byte)0xF1, (byte)0x72,
(byte)0xAB, (byte)0xB9, (byte)0x14, (byte)0x4E,
(byte)0xF5, (byte)0xF0, (byte)0x7A, (byte)0x8E,
(byte)0x45, (byte)0xFD, (byte)0x5B, (byte)0xF9,
(byte)0xA2, (byte)0x97, (byte)0x1B, (byte)0xAE,
(byte)0x2C, (byte)0x7B, (byte)0x6B, (byte)0x7C,
(byte)0x98, (byte)0xFE, (byte)0x58, (byte)0xDD,
(byte)0xBE, (byte)0xF6, (byte)0x1C, (byte)0x8E,
(byte)0xD0, (byte)0xA1, (byte)0x72
};
private static final byte bobPrivKeyEnc[] = {
(byte)0x30, (byte)0x81, (byte)0xE4, (byte)0x02,
(byte)0x01, (byte)0x00, (byte)0x30, (byte)0x81,
(byte)0x99, (byte)0x06, (byte)0x09, (byte)0x2A,
(byte)0x86, (byte)0x48, (byte)0x86, (byte)0xF7,
(byte)0x0D, (byte)0x01, (byte)0x03, (byte)0x01,
(byte)0x30, (byte)0x81, (byte)0x8B, (byte)0x02,
(byte)0x81, (byte)0x81, (byte)0x00, (byte)0xF4,
(byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E,
(byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20,
(byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91,
(byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33,
(byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45,
(byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88,
(byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B,
(byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3,
(byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43,
(byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18,
(byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55,
(byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38,
(byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C,
(byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3,
(byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE,
(byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5,
(byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1,
(byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18,
(byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84,
(byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6,
(byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19,
(byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A,
(byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9,
(byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0,
(byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02,
(byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D,
(byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41,
(byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD,
(byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19,
(byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2,
(byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9,
(byte)0x2F, (byte)0x78, (byte)0xC7, (byte)0x02,
(byte)0x01, (byte)0x02, (byte)0x02, (byte)0x02,
(byte)0x02, (byte)0x00, (byte)0x04, (byte)0x43,
(byte)0x02, (byte)0x41, (byte)0x00, (byte)0xE0,
(byte)0x31, (byte)0xE7, (byte)0x77, (byte)0xB8,
(byte)0xD0, (byte)0x7E, (byte)0x0A, (byte)0x9B,
(byte)0x94, (byte)0xD5, (byte)0x3D, (byte)0x33,
(byte)0x62, (byte)0x32, (byte)0x51, (byte)0xCE,
(byte)0x74, (byte)0x5C, (byte)0xA5, (byte)0x72,
(byte)0xD9, (byte)0x36, (byte)0xF3, (byte)0x8A,
(byte)0x3F, (byte)0x8B, (byte)0xC6, (byte)0xFE,
(byte)0xEF, (byte)0x94, (byte)0x8B, (byte)0x50,
(byte)0x41, (byte)0x9B, (byte)0x14, (byte)0xC8,
(byte)0xE9, (byte)0x1F, (byte)0x24, (byte)0x1F,
(byte)0x65, (byte)0x8E, (byte)0xD3, (byte)0x85,
(byte)0xD0, (byte)0x68, (byte)0x6C, (byte)0xF1,
(byte)0x79, (byte)0x45, (byte)0xD0, (byte)0x06,
(byte)0xA4, (byte)0xB8, (byte)0xE0, (byte)0x64,
(byte)0xF5, (byte)0x38, (byte)0x72, (byte)0x97,
(byte)0x00, (byte)0x23, (byte)0x5F
};
}

View File

@ -12,7 +12,7 @@ import java.util.Arrays;
* @bug 6937053 8005472 * @bug 6937053 8005472
* *
* @run clean TestSerializationMismatch * @run clean TestSerializationMismatch
* @run main TestSerializationMismatch * @run main/othervm TestSerializationMismatch
* *
*/ */
public class TestSerializationMismatch { public class TestSerializationMismatch {

View File

@ -0,0 +1,90 @@
/*
* 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 7150256
* @summary Basic Test for the DiagnosticCommandMBean
* @author Frederic Parain
*
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8125 DcmdMBeanDoubleInvocationTest
*/
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.*;
import javax.management.remote.*;
public class DcmdMBeanDoubleInvocationTest {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
public static void main(String[] args) {
MBeanServerConnection mbs = null;
try {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8125/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url);
mbs = connector.getMBeanServerConnection();
} catch(Throwable t) {
t.printStackTrace();
}
ObjectName name;
try {
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
MBeanInfo info = mbs.getMBeanInfo(name);
String[] helpArgs = {"-all", "\n", "VM.version"};
Object[] dcmdArgs = {helpArgs};
String[] signature = {String[].class.getName()};
String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
System.out.println(result);
} catch (RuntimeMBeanException ex) {
if (ex.getCause() instanceof IllegalArgumentException) {
System.out.println("Test passed");
return;
} else {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
} catch (InstanceNotFoundException | IntrospectionException
| ReflectionException | MalformedObjectNameException
| MBeanException|IOException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
System.out.println("Double commands have not been detected");
throw new RuntimeException("TEST FAILED");
}
}

View File

@ -0,0 +1,81 @@
/*
* 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 7150256
* @summary Basic Test for the DiagnosticCommandMBean
* @author Frederic Parain
*
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8129 DcmdMBeanInvocationTest
*/
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.*;
import javax.management.remote.*;
public class DcmdMBeanInvocationTest {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
public static void main(String[] args) {
MBeanServerConnection mbs = null;
try {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8129/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url);
mbs = connector.getMBeanServerConnection();
} catch(Throwable t) {
t.printStackTrace();
}
ObjectName name;
try {
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
MBeanInfo info = mbs.getMBeanInfo(name);
String[] helpArgs = {"-all"};
Object[] dcmdArgs = {helpArgs};
String[] signature = {String[].class.getName()};
String result = (String) mbs.invoke(name, "help", dcmdArgs, signature);
System.out.println(result);
} catch (InstanceNotFoundException | IntrospectionException
| ReflectionException | MalformedObjectNameException
| MBeanException|IOException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
System.out.println("Test passed");
}
}

View File

@ -0,0 +1,242 @@
/*
* 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 7150256
* @summary Permissions Tests for the DiagnosticCommandMBean
* @author Frederic Parain
*
* @run main/othervm DcmdMBeanPermissionsTest
*/
import java.lang.management.ManagementFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ReflectPermission;
import java.security.Permission;
import java.util.HashSet;
import java.util.Iterator;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanPermission;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.RuntimeMBeanException;
/**
*
* @author fparain
*/
public class DcmdMBeanPermissionsTest {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
static public class CustomSecurityManager extends SecurityManager {
private HashSet<Permission> grantedPermissions;
public CustomSecurityManager() {
grantedPermissions = new HashSet<Permission>();
}
public final void grantPermission(final Permission perm) {
grantedPermissions.add(perm);
}
public final void denyPermission(final Permission perm) {
Iterator<Permission> it = grantedPermissions.iterator();
while (it.hasNext()) {
Permission p = it.next();
if (p.equals(perm)) {
it.remove();
}
}
}
public final void checkPermission(final Permission perm) {
for (Permission p : grantedPermissions) {
if (p.implies(perm)) {
return;
}
}
throw new SecurityException(perm.toString());
}
};
static Permission createPermission(String classname, String name,
String action) {
Permission permission = null;
try {
Class c = Class.forName(classname);
if (action == null) {
try {
Constructor constructor = c.getConstructor(String.class);
permission = (Permission) constructor.newInstance(name);
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
}
if (permission == null) {
try {
Constructor constructor = c.getConstructor(String.class,
String.class);
permission = (Permission) constructor.newInstance(
name,
action);
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
if (permission == null) {
throw new RuntimeException("TEST FAILED");
}
return permission;
}
// return true if invokation triggered a SecurityException
static boolean invokeOperation(MBeanServer mbs, ObjectName on,
MBeanOperationInfo opInfo) {
try {
if (opInfo.getSignature().length == 0) {
mbs.invoke(on, opInfo.getName(),
new Object[0], new String[0]);
} else {
mbs.invoke(on, opInfo.getName(),
new Object[1], new String[]{ String[].class.getName()});
}
} catch (SecurityException ex) {
ex.printStackTrace();
return true;
} catch (RuntimeMBeanException ex) {
if (ex.getCause() instanceof SecurityException) {
//ex.printStackTrace();
return true;
}
} catch (MBeanException | InstanceNotFoundException
| ReflectionException ex) {
throw new RuntimeException("TEST FAILED");
}
return false;
}
static void testOperation(MBeanServer mbs, CustomSecurityManager sm,
ObjectName on, MBeanOperationInfo opInfo) {
System.out.println("Testing " + opInfo.getName());
Descriptor desc = opInfo.getDescriptor();
if (desc.getFieldValue("dcmd.permissionClass") == null) {
// No special permission required, execution should not trigger
// any security exception
if (invokeOperation(mbs, on, opInfo)) {
throw new RuntimeException("TEST FAILED");
}
} else {
// Building the required permission
Permission reqPerm = createPermission(
(String)desc.getFieldValue("dcmd.permissionClass"),
(String)desc.getFieldValue("dcmd.permissionName"),
(String)desc.getFieldValue("dcmd.permissionAction"));
// Paranoid mode: check that the SecurityManager has not already
// been granted the permission
sm.denyPermission(reqPerm);
// A special permission is required for this operation,
// invoking it without the permission granted must trigger
// a security exception
if(!invokeOperation(mbs, on, opInfo)) {
throw new RuntimeException("TEST FAILED");
}
// grant the permission and re-try invoking the operation
sm.grantPermission(reqPerm);
if(invokeOperation(mbs, on, opInfo)) {
throw new RuntimeException("TEST FAILED");
}
// Clean up
sm.denyPermission(reqPerm);
}
}
public static void main(final String[] args) {
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName on = null;
try {
on = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
} catch (MalformedObjectNameException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
MBeanInfo info = null;
try {
info = mbs.getMBeanInfo(on);
} catch (InstanceNotFoundException | IntrospectionException
| ReflectionException ex) {
ex.printStackTrace();
throw new RuntimeException("TEST FAILED");
}
CustomSecurityManager sm = new CustomSecurityManager();
System.setSecurityManager(sm);
// Set of permission required to run the test cleanly
// Some permissions are required by the MBeanServer and other
// platform services (RuntimePermission("createClassLoader"),
// ReflectPermission("suppressAccessChecks"),
// java.util.logging.LoggingPermission("control"),
// RuntimePermission("exitVM.97")).
// Other permissions are required by commands being invoked
// in the test (for instance, RuntimePermission("modifyThreadGroup")
// and RuntimePermission("modifyThread") are checked when
// runFinalization() is invoked by the gcRunFinalization command.
sm.grantPermission(new RuntimePermission("createClassLoader"));
sm.grantPermission(new ReflectPermission("suppressAccessChecks"));
sm.grantPermission(new java.util.logging.LoggingPermission("control", ""));
sm.grantPermission(new java.lang.RuntimePermission("exitVM.97"));
sm.grantPermission(new java.lang.RuntimePermission("modifyThreadGroup"));
sm.grantPermission(new java.lang.RuntimePermission("modifyThread"));
for(MBeanOperationInfo opInfo : info.getOperations()) {
Permission opPermission = new MBeanPermission(info.getClassName(),
opInfo.getName(),
on,
"invoke");
sm.grantPermission(opPermission);
testOperation(mbs, sm, on, opInfo);
sm.denyPermission(opPermission);
}
System.out.println("TEST PASSED");
}
}

View File

@ -0,0 +1,113 @@
/*
* 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 7150256
* @summary Basic Test for the DiagnosticCommandMBean
* @author Frederic Parain
*
* @run main/othervm -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8127 DcmdMBeanTest
*/
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.*;
import javax.management.remote.*;
public class DcmdMBeanTest {
private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
public static void main(String[] args) {
MBeanServerConnection mbs = null;
try {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8127/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url);
mbs = connector.getMBeanServerConnection();
} catch(Throwable t) {
t.printStackTrace();
}
ObjectName name;
try {
name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
MBeanInfo info = mbs.getMBeanInfo(name);
// the test should check that the MBean doesn't have any
// Attribute, notification or constructor. Current version only
// check operations
System.out.println("Class Name:"+info.getClassName());
System.out.println("Description:"+info.getDescription());
MBeanOperationInfo[] opInfo = info.getOperations();
System.out.println("Operations:");
for(int i=0; i<opInfo.length; i++) {
printOperation(opInfo[i]);
System.out.println("\n@@@@@@\n");
}
} catch (InstanceNotFoundException|IntrospectionException|ReflectionException
|MalformedObjectNameException|IOException ex) {
Logger.getLogger(DcmdMBeanTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
static void printOperation(MBeanOperationInfo info) {
System.out.println("Name: "+info.getName());
System.out.println("Description: "+info.getDescription());
System.out.println("Return Type: "+info.getReturnType());
System.out.println("Impact: "+info.getImpact());
Descriptor desc = info.getDescriptor();
System.out.println("Descriptor");
for(int i=0; i<desc.getFieldNames().length; i++) {
if(desc.getFieldNames()[i].compareTo("dcmd.arguments") == 0) {
System.out.println("\t"+desc.getFieldNames()[i]+":");
Descriptor desc2 =
(Descriptor)desc.getFieldValue(desc.getFieldNames()[i]);
for(int j=0; j<desc2.getFieldNames().length; j++) {
System.out.println("\t\t"+desc2.getFieldNames()[j]+"=");
Descriptor desc3 =
(Descriptor)desc2.getFieldValue(desc2.getFieldNames()[j]);
for(int k=0; k<desc3.getFieldNames().length; k++) {
System.out.println("\t\t\t"+desc3.getFieldNames()[k]+"="
+desc3.getFieldValue(desc3.getFieldNames()[k]));
}
}
} else {
System.out.println("\t"+desc.getFieldNames()[i]+"="
+desc.getFieldValue(desc.getFieldNames()[i]));
}
}
}
}

View File

@ -29,6 +29,7 @@ import java.nio.file.spi.*;
import java.nio.file.attribute.*; import java.nio.file.attribute.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.*; import java.util.zip.*;
import static java.nio.file.StandardOpenOption.*; import static java.nio.file.StandardOpenOption.*;
@ -48,6 +49,7 @@ public class ZipFSTester {
test0(fs); test0(fs);
test1(fs); test1(fs);
test2(fs); // more tests test2(fs); // more tests
testTime(Paths.get(args[0]));
} }
} }
@ -337,6 +339,46 @@ public class ZipFSTester {
Files.delete(fs3Path); Files.delete(fs3Path);
} }
// test file stamp
static void testTime(Path src) throws Exception {
// create a new filesystem, copy this file into it
Map<String, Object> env = new HashMap<String, Object>();
env.put("create", "true");
Path fsPath = getTempPath();
FileSystem fs = newZipFileSystem(fsPath, env);
System.out.println("test copy with timestamps...");
// copyin
Path dst = getPathWithParents(fs, "me");
Files.copy(src, dst, COPY_ATTRIBUTES);
checkEqual(src, dst);
BasicFileAttributes attrs = Files
.getFileAttributeView(src, BasicFileAttributeView.class)
.readAttributes();
System.out.println("mtime: " + attrs.lastModifiedTime());
System.out.println("ctime: " + attrs.creationTime());
System.out.println("atime: " + attrs.lastAccessTime());
System.out.println(" ==============>");
BasicFileAttributes dstAttrs = Files
.getFileAttributeView(dst, BasicFileAttributeView.class)
.readAttributes();
System.out.println("mtime: " + dstAttrs.lastModifiedTime());
System.out.println("ctime: " + dstAttrs.creationTime());
System.out.println("atime: " + dstAttrs.lastAccessTime());
// 1-second granularity
if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) !=
dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) ||
attrs.lastAccessTime().to(TimeUnit.SECONDS) !=
dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) ||
attrs.creationTime().to(TimeUnit.SECONDS) !=
dstAttrs.creationTime().to(TimeUnit.SECONDS)) {
throw new RuntimeException("Timestamp Copy Failed!");
}
Files.delete(fsPath);
}
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env) private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
throws Exception throws Exception
{ {

View File

@ -22,7 +22,7 @@
# #
# @test # @test
# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 # @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
# 7157656 8002390 # 7157656 8002390 7012868 7012856
# @summary Test ZipFileSystem demo # @summary Test ZipFileSystem demo
# @build Basic PathOps ZipFSTester # @build Basic PathOps ZipFSTester
# @run shell basic.sh # @run shell basic.sh

View File

@ -277,8 +277,8 @@ public class General {
{ {
check(ans, ask + slash); check(ans, ask + slash);
checkNames(depth, create, checkNames(depth, create,
ans, ans.endsWith(File.separator) ? ans : ans + File.separator,
ask); ask + slash);
} }
@ -308,9 +308,6 @@ public class General {
String ans, String ask) String ans, String ask)
throws Exception throws Exception
{ {
ans = ans.endsWith(File.separator) ? ans : ans + File.separator;
ask = ask.endsWith(File.separator) ? ask : ask + File.separator;
int d = depth - 1; int d = depth - 1;
File f = new File(ans); File f = new File(ans);
String n; String n;

View File

@ -50,13 +50,13 @@ public class GeneralWin32 extends General {
private static final int DEPTH = 2; private static final int DEPTH = 2;
private static String baseDir = null; private static String baseDir = null;
private static String userDir = null; private static String userDir = null;
private static String relative = null;
/* Pathnames relative to working directory */ /* Pathnames relative to working directory */
private static void checkCaseLookup() throws IOException { private static void checkCaseLookup() throws IOException {
/* Use long names here to avoid 8.3 format, which Samba servers often /* Use long names here to avoid 8.3 format, which Samba servers often
force to lowercase */ force to lowercase */
String relative = baseDir.substring(userDir.length() + 1);
File d1 = new File(relative, "XyZzY0123"); File d1 = new File(relative, "XyZzY0123");
File d2 = new File(d1, "FOO_bar_BAZ"); File d2 = new File(d1, "FOO_bar_BAZ");
File f = new File(d2, "GLORPified"); File f = new File(d2, "GLORPified");
@ -79,9 +79,9 @@ public class GeneralWin32 extends General {
case of filenames, rather than just using the input case */ case of filenames, rather than just using the input case */
File y = new File(userDir, f.getPath()); File y = new File(userDir, f.getPath());
String ans = y.getPath(); String ans = y.getPath();
check(ans, relative + "\\" + "XyZzY0123\\FOO_bar_BAZ\\GLORPified"); check(ans, relative + "XyZzY0123\\FOO_bar_BAZ\\GLORPified");
check(ans, relative + "\\" + "xyzzy0123\\foo_bar_baz\\glorpified"); check(ans, relative + "xyzzy0123\\foo_bar_baz\\glorpified");
check(ans, relative + "\\" + "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED"); check(ans, relative + "XYZZY0123\\FOO_BAR_BAZ\\GLORPIFIED");
} }
private static void checkWild(File f) throws Exception { private static void checkWild(File f) throws Exception {
@ -103,8 +103,7 @@ public class GeneralWin32 extends General {
private static void checkRelativePaths() throws Exception { private static void checkRelativePaths() throws Exception {
checkCaseLookup(); checkCaseLookup();
checkWildCards(); checkWildCards();
String relative = baseDir.substring(userDir.length() + 1); checkNames(3, true, baseDir, relative);
checkNames(3, true, baseDir.toString(), relative);
} }
@ -136,7 +135,6 @@ public class GeneralWin32 extends General {
String ans = exists ? df.getAbsolutePath() : d; String ans = exists ? df.getAbsolutePath() : d;
if (!ans.endsWith("\\")) if (!ans.endsWith("\\"))
ans = ans + "\\"; ans = ans + "\\";
String relative = baseDir.substring(userDir.length() + 1);
checkNames(depth, false, ans + relative, d + relative); checkNames(depth, false, ans + relative, d + relative);
} }
@ -171,15 +169,16 @@ public class GeneralWin32 extends General {
return; return;
} }
if (args.length > 0) debug = true; if (args.length > 0) debug = true;
userDir = System.getProperty("user.dir"); userDir = System.getProperty("user.dir") + '\\';
baseDir = initTestData(6); baseDir = initTestData(6) + '\\';
relative = baseDir.substring(userDir.length());
checkRelativePaths(); checkRelativePaths();
checkDrivePaths(); checkDrivePaths();
checkUncPaths(); checkUncPaths();
} }
private static String initTestData(int maxDepth) throws IOException { private static String initTestData(int maxDepth) throws IOException {
File parent = new File(System.getProperty("user.dir")); File parent = new File(userDir);
String baseDir = null; String baseDir = null;
maxDepth = maxDepth < DEPTH + 2 ? DEPTH + 2 : maxDepth; maxDepth = maxDepth < DEPTH + 2 ? DEPTH + 2 : maxDepth;
for (int i = 0; i < maxDepth; i ++) { for (int i = 0; i < maxDepth; i ++) {

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2012, 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.annotations.DataProvider;
import org.testng.annotations.Test;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Arrays;
import java.util.List;
import java.util.function.LongFunction;
import java.util.function.Function;
import static org.testng.Assert.assertEquals;
/**
* @test
* @run testng IntegralPrimitiveToString
* @summary test string conversions for primitive integral types.
* @author Mike Duigou
*/
public class IntegralPrimitiveToString {
@Test(dataProvider="numbers")
public <N extends Number> void testToString(String description,
Function<N, BigInteger> converter,
Function<N, BigInteger> unsignedConverter,
N[] values,
Stringifier<N>[] stringifiers) {
System.out.printf("%s : conversions: %d values: %d\n", description, stringifiers.length, values.length);
for( N value : values) {
BigInteger asBigInt = converter.apply(value);
BigInteger asUnsignedBigInt = unsignedConverter.apply(value);
for(Stringifier<N> stringifier : stringifiers) {
stringifier.assertMatchingToString(value, asBigInt, asUnsignedBigInt, description);
}
}
}
static class Stringifier<N extends Number> {
final boolean signed;
final int radix;
final Function<N,String> toString;
Stringifier(boolean signed, int radix, Function<N,String> toString) {
this.signed = signed;
this.radix = radix;
this.toString = toString;
}
public void assertMatchingToString(N value, BigInteger asSigned, BigInteger asUnsigned, String description) {
String expected = signed
? asSigned.toString(radix)
: asUnsigned.toString(radix);
String actual = toString.apply(value);
assertEquals(actual, expected, description + " conversion should be the same");
}
}
@DataProvider(name="numbers", parallel=true)
public Iterator<Object[]> testSetProvider() {
return Arrays.asList(
new Object[] { "Byte",
(Function<Byte,BigInteger>) b -> BigInteger.valueOf((long) b),
(Function<Byte,BigInteger>) b -> BigInteger.valueOf(Integer.toUnsignedLong((byte) b)),
numberProvider((LongFunction<Byte>) l -> Byte.valueOf((byte) l), Byte.SIZE),
new Stringifier[] {
new Stringifier<Byte>(true, 10, b -> b.toString()),
new Stringifier<Byte>(true, 10, b -> Byte.toString(b))
}
},
new Object[] { "Short",
(Function<Short,BigInteger>) s -> BigInteger.valueOf((long) s),
(Function<Short,BigInteger>) s -> BigInteger.valueOf(Integer.toUnsignedLong((short) s)),
numberProvider((LongFunction<Short>) l -> Short.valueOf((short) l), Short.SIZE),
new Stringifier[] {
new Stringifier<Short>(true, 10, s -> s.toString()),
new Stringifier<Short>(true, 10, s -> Short.toString( s))
}
},
new Object[] { "Integer",
(Function<Integer,BigInteger>) i -> BigInteger.valueOf((long) i),
(Function<Integer,BigInteger>) i -> BigInteger.valueOf(Integer.toUnsignedLong(i)),
numberProvider((LongFunction<Integer>) l -> Integer.valueOf((int) l), Integer.SIZE),
new Stringifier[] {
new Stringifier<Integer>(true, 10, i -> i.toString()),
new Stringifier<Integer>(true, 10, i -> Integer.toString(i)),
new Stringifier<Integer>(false, 2, Integer::toBinaryString),
new Stringifier<Integer>(false, 16, Integer::toHexString),
new Stringifier<Integer>(false, 8, Integer::toOctalString),
new Stringifier<Integer>(true, 2, i -> Integer.toString(i, 2)),
new Stringifier<Integer>(true, 8, i -> Integer.toString(i, 8)),
new Stringifier<Integer>(true, 10, i -> Integer.toString(i, 10)),
new Stringifier<Integer>(true, 16, i -> Integer.toString(i, 16)),
new Stringifier<Integer>(true, Character.MAX_RADIX, i -> Integer.toString(i, Character.MAX_RADIX)),
new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i)),
new Stringifier<Integer>(false, 2, i -> Integer.toUnsignedString(i, 2)),
new Stringifier<Integer>(false, 8, i -> Integer.toUnsignedString(i, 8)),
new Stringifier<Integer>(false, 10, i -> Integer.toUnsignedString(i, 10)),
new Stringifier<Integer>(false, 16, i -> Integer.toUnsignedString(i, 16)),
new Stringifier<Integer>(false, Character.MAX_RADIX, i -> Integer.toUnsignedString(i, Character.MAX_RADIX))
}
},
new Object[] { "Long",
(Function<Long, BigInteger>) BigInteger::valueOf,
(Function<Long, BigInteger>) l -> {
if (l >= 0) {
return BigInteger.valueOf((long) l);
} else {
int upper = (int)(l >>> 32);
int lower = (int) (long) l;
// return (upper << 32) + lower
return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
}
},
numberProvider((LongFunction<Long>) Long::valueOf, Long.SIZE),
new Stringifier[] {
new Stringifier<Long>(true, 10, l -> l.toString()),
new Stringifier<Long>(true, 10, l -> Long.toString(l)),
new Stringifier<Long>(false, 2, Long::toBinaryString),
new Stringifier<Long>(false, 16, Long::toHexString),
new Stringifier<Long>(false, 8, Long::toOctalString),
new Stringifier<Long>(true, 2, l -> Long.toString(l, 2)),
new Stringifier<Long>(true, 8, l -> Long.toString(l, 8)),
new Stringifier<Long>(true, 10, l -> Long.toString(l, 10)),
new Stringifier<Long>(true, 16, l -> Long.toString(l, 16)),
new Stringifier<Long>(true, Character.MAX_RADIX, l -> Long.toString(l, Character.MAX_RADIX)),
new Stringifier<Long>(false, 10, Long::toUnsignedString),
new Stringifier<Long>(false, 2, l -> Long.toUnsignedString(l, 2)),
new Stringifier<Long>(false, 8, l-> Long.toUnsignedString(l, 8)),
new Stringifier<Long>(false, 10, l -> Long.toUnsignedString(l, 10)),
new Stringifier<Long>(false, 16, l -> Long.toUnsignedString(l, 16)),
new Stringifier<Long>(false, Character.MAX_RADIX, l -> Long.toUnsignedString(l, Character.MAX_RADIX))
}
}
).iterator();
}
private static final long[] SOME_PRIMES = {
3L, 5L, 7L, 11L, 13L, 17L, 19L, 23L, 29L, 31L, 37L, 41L, 43L, 47L, 53L,
59L, 61L, 71L, 73L, 79L, 83L, 89L, 97L, 101L, 103L, 107L, 109L, 113L,
5953L, 5981L, 5987L, 6007L, 6011L, 6029L, 6037L, 6043L, 6047L, 6053L,
16369L, 16381L, 16411L, 32749L, 32771L, 65521L, 65537L,
(long) Integer.MAX_VALUE };
public <N extends Number> N[] numberProvider(LongFunction<N> boxer, int bits, N... extras) {
List<N> numbers = new ArrayList<>();
for(int bitmag = 0; bitmag < bits; bitmag++) {
long value = 1L << bitmag;
numbers.add(boxer.apply(value));
numbers.add(boxer.apply(value - 1));
numbers.add(boxer.apply(value + 1));
numbers.add(boxer.apply(-value));
for(int divisor = 0; divisor < SOME_PRIMES.length && value < SOME_PRIMES[divisor]; divisor++) {
numbers.add(boxer.apply(value - SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value + SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value * SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value / SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value | SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value & SOME_PRIMES[divisor]));
numbers.add(boxer.apply(value ^ SOME_PRIMES[divisor]));
}
}
numbers.addAll(Arrays.asList(extras));
return (N[]) numbers.toArray(new Number[numbers.size()]);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,10 @@ import java.util.*;
import javax.management.*; import javax.management.*;
public class MXBeanBehavior { public class MXBeanBehavior {
// Exclude list: list of platform MBeans that are not MXBeans
public static final HashSet<String> excludeList = new HashSet<>(
Arrays.asList("com.sun.management:type=DiagnosticCommand"));
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
@ -92,6 +96,10 @@ public class MXBeanBehavior {
by generic MXBean tests. by generic MXBean tests.
*/ */
private static void test(MBeanServer mbs, ObjectName name) throws Exception { private static void test(MBeanServer mbs, ObjectName name) throws Exception {
if(excludeList.contains(name.getCanonicalName())) {
// Skipping not MXBean objects.
return;
}
System.out.println("Testing: " + name); System.out.println("Testing: " + name);
MBeanInfo mbi = mbs.getMBeanInfo(name); MBeanInfo mbi = mbs.getMBeanInfo(name);

Some files were not shown because too many files have changed in this diff Show More