提交 c0960284 编写于 作者: L lana

Merge

...@@ -214,3 +214,5 @@ d5228e624826a10ccc5b05f30ad8d839b58fe48d jdk8-b87 ...@@ -214,3 +214,5 @@ d5228e624826a10ccc5b05f30ad8d839b58fe48d jdk8-b87
c63eda8f63008a4398d2c22ac8d72f7fef6f9238 jdk8-b90 c63eda8f63008a4398d2c22ac8d72f7fef6f9238 jdk8-b90
169451cf0cc53bde5af24f9820ea3f35ec4b4df4 jdk8-b91 169451cf0cc53bde5af24f9820ea3f35ec4b4df4 jdk8-b91
a2a2a91075ad85becbe10a39d7fd04ef9bea8df5 jdk8-b92 a2a2a91075ad85becbe10a39d7fd04ef9bea8df5 jdk8-b92
691d6c6cd332d98b0f0221445a73906776f31f72 jdk8-b93
51479fa56b7c4363c6d87c2e8b898d8185cf4b22 jdk8-b94
# #
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1999, 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
...@@ -432,40 +432,3 @@ RC_FLAGS += -d "JDK_BUILD_ID=$(JDK_RC_BUILD_ID)" \ ...@@ -432,40 +432,3 @@ RC_FLAGS += -d "JDK_BUILD_ID=$(JDK_RC_BUILD_ID)" \
-d "JDK_COPYRIGHT=$(JDK_RC_COPYRIGHT)" \ -d "JDK_COPYRIGHT=$(JDK_RC_COPYRIGHT)" \
-d "JDK_NAME=$(JDK_RC_NAME)" \ -d "JDK_NAME=$(JDK_RC_NAME)" \
-d "JDK_FVER=$(JDK_RC_FVER)" -d "JDK_FVER=$(JDK_RC_FVER)"
# Enable 7-Zip LZMA file (de)compression for Java Kernel if it is available
ifeq ($(ARCH_DATA_MODEL), 32)
ifneq ($(KERNEL), off)
# This is a hack to use until 7-Zip (and UPX) bundles can be put
# under /java/devtools.
ifndef DEPLOY_TOPDIR
DEPLOY_TOPDIR=$(JDK_TOPDIR)/../deploy
endif
# Uncomment this block to cause build failure if above assumption false
#DCHK = $(shell if [ ! -d $(DEPLOY_TOPDIR) ] ; then \
# $(ECHO) deploy_not_a_peer_of_j2se ; \
#fi )
#ifeq ($(DCHK), deploy_not_a_peer_of_j2se)
# If a build failure points to control coming here it means
# it means deploy is not in the same directory
# as j2se. Java Kernel can't tolerate that for the time being.
#endif
EC_TMP = $(shell if [ -d $(DEPLOY_TOPDIR)/make/lzma ] ; then \
$(ECHO) true ; \
else \
$(ECHO) false ; \
fi )
ifeq ($(EC_TMP), true)
EXTRA_COMP_INSTALL_PATH = lib\\\\deploy\\\\lzma.dll
# Crazy but true: deploy/make/plugin/jinstall/Makefile.jkernel does
# not include deploy/make/common/Defs-windows.gmk, either directly
# or indirectly. But it does include this file, so redundantly declare
# these variables that are in deploy/make/common/Defs-windows.gmk for
# the sake of the Java Kernel part of the deploy build. Whew!
EXTRA_COMP_LIB_NAME = lzma.dll
EXTRA_COMP_PATH = $(OUTPUTDIR)/tmp/deploy/lzma/win32/obj
EXTRA_COMP_CMD_PATH = $(EXTRA_COMP_PATH)/lzma.exe
EXTRA_COMP_LIB_PATH = $(EXTRA_COMP_PATH)/$(EXTRA_COMP_LIB_NAME)
endif
endif
endif
# #
# 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 @@ ...@@ -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 \
......
# #
# 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 @@ ...@@ -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 \
......
# #
# 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 { ...@@ -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;
......
...@@ -31,6 +31,8 @@ BUILDDIR = ../.. ...@@ -31,6 +31,8 @@ BUILDDIR = ../..
LIBRARY = jdwp LIBRARY = jdwp
PRODUCT = jpda PRODUCT = jpda
LIBRARY_SUPPORTS_FULL_DEBUG_SYMBOLS=1
FILES_m = mapfile-vers FILES_m = mapfile-vers
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
......
...@@ -390,12 +390,9 @@ ifeq ($(PLATFORM), linux) ...@@ -390,12 +390,9 @@ ifeq ($(PLATFORM), linux)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv LINUX # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv LINUX
ifdef OPENJDK ifdef OPENJDK
FONTCONFIGS_SRC = $(PLATFORM_SRC)/classes/sun/awt/fontconfigs FONTCONFIGS_SRC =
_FONTCONFIGS = \ _FONTCONFIGS =
fontconfig.properties \
fontconfig.SuSE.properties \
fontconfig.Ubuntu.properties \
fontconfig.Fedora.properties
else else
FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs
...@@ -441,7 +438,11 @@ endif # PLATFORM ...@@ -441,7 +438,11 @@ endif # PLATFORM
FONTCONFIGS = $(_FONTCONFIGS:%=$(LIBDIR)/%.src) FONTCONFIGS = $(_FONTCONFIGS:%=$(LIBDIR)/%.src)
BINARYFONTCONFIGS = $(_FONTCONFIGS:%.properties=$(LIBDIR)/%.bfc) BINARYFONTCONFIGS = $(_FONTCONFIGS:%.properties=$(LIBDIR)/%.bfc)
ifneq ("x$(_FONTCONFIGS)", "x")
fontconfigs: $(FONTCONFIGS) $(BINARYFONTCONFIGS) fontconfigs: $(FONTCONFIGS) $(BINARYFONTCONFIGS)
else
fontconfigs:
endif
$(LIBDIR)/%.src: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)% $(LIBDIR)/%.src: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%
$(install-file) $(install-file)
...@@ -455,9 +456,13 @@ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \ ...@@ -455,9 +456,13 @@ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
$(call chmod-file, 444) $(call chmod-file, 444)
@$(java-vm-cleanup) @$(java-vm-cleanup)
ifneq ("x$(_FONTCONFIGS)", "x")
fontconfigs.clean : fontconfigs.clean :
$(RM) $(FONTCONFIGS) $(RM) $(FONTCONFIGS)
$(RM) $(BINARYFONTCONFIGS) $(RM) $(BINARYFONTCONFIGS)
else
fontconfigs.clean :
endif
ifeq ($(PLATFORM), windows) ifeq ($(PLATFORM), windows)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv WINDOWS # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv WINDOWS
......
...@@ -5,6 +5,8 @@ ...@@ -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 @@ ...@@ -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
......
...@@ -39,6 +39,7 @@ ...@@ -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 { ...@@ -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);
} }
/** /**
......
...@@ -342,7 +342,7 @@ $(eval $(call SetupJavaCompilation,BUILD_JOBJC,\ ...@@ -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,\ ...@@ -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,\
......
...@@ -95,6 +95,9 @@ define SetupLauncher ...@@ -95,6 +95,9 @@ define SetupLauncher
$1_PLIST_FILE:=Info-cmdline.plist $1_PLIST_FILE:=Info-cmdline.plist
ifneq ($(11),) ifneq ($(11),)
$1_PLIST_FILE:=$(11) $1_PLIST_FILE:=$(11)
ifneq ($$(findstring privileged,$$($1_PLIST_FILE)),)
$1_CODESIGN:=true
endif
endif endif
$1_LDFLAGS += -Wl,-all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \ $1_LDFLAGS += -Wl,-all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \
...@@ -174,7 +177,8 @@ define SetupLauncher ...@@ -174,7 +177,8 @@ define SetupLauncher
-D "JDK_INTERNAL_NAME=$1" \ -D "JDK_INTERNAL_NAME=$1" \
-D "JDK_FTYPE=0x1L" \ -D "JDK_FTYPE=0x1L" \
$7,\ $7,\
MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/java.manifest) MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/java.manifest,\
CODESIGN:=$$($1_CODESIGN))
BUILD_LAUNCHERS += $$(BUILD_LAUNCHER_$1) BUILD_LAUNCHERS += $$(BUILD_LAUNCHER_$1)
......
...@@ -1143,7 +1143,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJDWP,\ ...@@ -1143,7 +1143,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJDWP,\
-D "JDK_INTERNAL_NAME=jdwp" \ -D "JDK_INTERNAL_NAME=jdwp" \
-D "JDK_FTYPE=0x2L",\ -D "JDK_FTYPE=0x2L",\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libjdwp,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libjdwp,\
DEBUG_SYMBOLS:=$(DEBUG_ALL_BINARIES))) DEBUG_SYMBOLS:=true))
$(BUILD_LIBJDWP) : $(BUILD_LIBJAVA) $(BUILD_LIBJDWP) : $(BUILD_LIBJAVA)
...@@ -2609,21 +2609,22 @@ endif ...@@ -2609,21 +2609,22 @@ endif
########################################################################################## ##########################################################################################
BUILD_LIBKRB5_NAME:= ifneq ($(BUILD_CRYPTO),no)
ifeq ($(OPENJDK_TARGET_OS), windows) BUILD_LIBKRB5_NAME:=
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_LIBKRB5_NAME:=w2k_lsa_auth BUILD_LIBKRB5_NAME:=w2k_lsa_auth
BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5 BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5
BUILD_LIBKRB5_LIBS:=advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \ BUILD_LIBKRB5_LIBS:=advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \
gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \ gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib
else ifeq ($(OPENJDK_TARGET_OS), macosx) else ifeq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBKRB5_NAME:=osxkrb5 BUILD_LIBKRB5_NAME:=osxkrb5
BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/share/native/sun/security/krb5 BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/share/native/sun/security/krb5
BUILD_LIBKRB5_LIBS:=-framework Kerberos BUILD_LIBKRB5_LIBS:=-framework Kerberos
endif endif
ifneq ($(BUILD_LIBKRB5_NAME),) ifneq ($(BUILD_LIBKRB5_NAME),)
$(eval $(call SetupNativeCompilation,BUILD_LIBKRB5,\ $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5,\
LIBRARY:=$(BUILD_LIBKRB5_NAME),\ LIBRARY:=$(BUILD_LIBKRB5_NAME),\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\ OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(BUILD_LIBKRB5_SRC),\ SRC:=$(BUILD_LIBKRB5_SRC),\
...@@ -2643,7 +2644,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5,\ ...@@ -2643,7 +2644,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBKRB5,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libkrb5,\ OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libkrb5,\
DEBUG_SYMBOLS:=$(DEBUG_ALL_BINARIES))) DEBUG_SYMBOLS:=$(DEBUG_ALL_BINARIES)))
BUILD_LIBRARIES += $(BUILD_LIBKRB5) BUILD_LIBRARIES += $(BUILD_LIBKRB5)
endif
endif endif
########################################################################################## ##########################################################################################
......
...@@ -467,10 +467,15 @@ $(JCE_MANIFEST): $(MAINMANIFEST) ...@@ -467,10 +467,15 @@ $(JCE_MANIFEST): $(MAINMANIFEST)
$(MV) $@.tmp $@ $(MV) $@.tmp $@
########################################################################################## ##########################################################################################
# For all security jars, always build the jar, but for closed, install the prebuilt signed # For security and crypto jars, always build the jar, but for closed, install the prebuilt
# version instead of the newly built jar. Unsigned jars are treated as intermediate targets # signed version instead of the newly built jar. Unsigned jars are treated as intermediate
# and explicitly added to the JARS list. For open, signing is not needed. See SignJars.gmk # targets and explicitly added to the JARS list. For open, signing is not needed. See
# for more information. # SignJars.gmk for more information.
#
# The source for the crypto jars is not available for all licensees. The BUILD_CRYPTO
# variable is set to no if these jars can't be built to skip that step of the build.
# Note that for OPENJDK, the build will fail if BUILD_CRYPTO=no since then there is no
# other way to get the jars than to build them.
SUNPKCS11_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunpkcs11.jar SUNPKCS11_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunpkcs11.jar
SUNPKCS11_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/sunpkcs11.jar SUNPKCS11_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/sunpkcs11.jar
...@@ -540,7 +545,8 @@ $(eval $(call SetupArchive,BUILD_SWINGBEANS_JAR,,\ ...@@ -540,7 +545,8 @@ $(eval $(call SetupArchive,BUILD_SWINGBEANS_JAR,,\
SUNJCE_PROVIDER_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunjce_provider.jar SUNJCE_PROVIDER_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunjce_provider.jar
SUNJCE_PROVIDER_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/sunjce_provider.jar SUNJCE_PROVIDER_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/sunjce_provider.jar
$(eval $(call SetupArchive,BUILD_SUNJCE_PROVIDER_JAR,,\ ifneq ($(BUILD_CRYPTO),no)
$(eval $(call SetupArchive,BUILD_SUNJCE_PROVIDER_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes, \ SRCS:=$(JDK_OUTPUTDIR)/classes, \
SUFFIXES:=.class,\ SUFFIXES:=.class,\
INCLUDES:= com/sun/crypto/provider,\ INCLUDES:= com/sun/crypto/provider,\
...@@ -548,7 +554,10 @@ $(eval $(call SetupArchive,BUILD_SUNJCE_PROVIDER_JAR,,\ ...@@ -548,7 +554,10 @@ $(eval $(call SetupArchive,BUILD_SUNJCE_PROVIDER_JAR,,\
MANIFEST:=$(JCE_MANIFEST), \ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true)) SKIP_METAINF := true))
$(SUNJCE_PROVIDER_JAR_UNSIGNED): $(JCE_MANIFEST) $(SUNJCE_PROVIDER_JAR_UNSIGNED): $(JCE_MANIFEST)
JARS += $(SUNJCE_PROVIDER_JAR_UNSIGNED)
endif
ifndef OPENJDK ifndef OPENJDK
SUNJCE_PROVIDER_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/sunjce_provider.jar SUNJCE_PROVIDER_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/sunjce_provider.jar
...@@ -560,14 +569,13 @@ else ...@@ -560,14 +569,13 @@ else
$(install-file) $(install-file)
endif endif
JARS += $(SUNJCE_PROVIDER_JAR_UNSIGNED)
########################################################################################## ##########################################################################################
JCE_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/jce.jar JCE_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/jce.jar
JCE_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/jce.jar JCE_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/jce.jar
$(eval $(call SetupArchive,BUILD_JCE_JAR,,\ ifneq ($(BUILD_CRYPTO),no)
$(eval $(call SetupArchive,BUILD_JCE_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes, \ SRCS:=$(JDK_OUTPUTDIR)/classes, \
SUFFIXES:=.class,\ SUFFIXES:=.class,\
INCLUDES:= javax/crypto sun/security/internal,\ INCLUDES:= javax/crypto sun/security/internal,\
...@@ -575,101 +583,106 @@ $(eval $(call SetupArchive,BUILD_JCE_JAR,,\ ...@@ -575,101 +583,106 @@ $(eval $(call SetupArchive,BUILD_JCE_JAR,,\
MANIFEST:=$(JCE_MANIFEST), \ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true)) SKIP_METAINF := true))
$(JCE_JAR_UNSIGNED): $(JCE_MANIFEST) $(JCE_JAR_UNSIGNED): $(JCE_MANIFEST)
JARS += $(JCE_JAR_UNSIGNED)
endif
ifndef OPENJDK ifndef OPENJDK
JCE_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/jce.jar JCE_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/jce.jar
$(JCE_JAR_DST) : $(JCE_JAR_SRC) $(JCE_JAR_DST) : $(JCE_JAR_SRC)
@$(ECHO) $(LOG_INFO) "\n>>>Installing prebuilt jce.jar..." @$(ECHO) $(LOG_INFO) "\n>>>Installing prebuilt jce.jar..."
$(install-file) $(install-file)
else else
$(JCE_JAR_DST) : $(JCE_JAR_UNSIGNED) $(JCE_JAR_DST) : $(JCE_JAR_UNSIGNED)
$(install-file) $(install-file)
endif endif
JARS += $(JCE_JAR_UNSIGNED)
########################################################################################## ##########################################################################################
US_EXPORT_POLICY_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/security/US_export_policy.jar US_EXPORT_POLICY_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/security/US_export_policy.jar
US_EXPORT_POLICY_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/US_export_policy.jar US_EXPORT_POLICY_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/US_export_policy.jar
# ifneq ($(BUILD_CRYPTO),no)
# TODO fix so that SetupArchive does not write files into SRCS #
# then we don't need this extra copying # TODO fix so that SetupArchive does not write files into SRCS
# # then we don't need this extra copying
# NOTE: We currently do not place restrictions on our limited export
# policy. This was not a typo. # NOTE: We currently do not place restrictions on our limited export
# # policy. This was not a typo.
US_EXPORT_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/unlimited #
US_EXPORT_POLICY_JAR_TMP := $(IMAGES_OUTPUTDIR)/US_export_policy_jar.tmp US_EXPORT_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/unlimited
US_EXPORT_POLICY_JAR_TMP := $(IMAGES_OUTPUTDIR)/US_export_policy_jar.tmp
$(US_EXPORT_POLICY_JAR_TMP)/% : $(US_EXPORT_POLICY_JAR_SRC_DIR)/% $(US_EXPORT_POLICY_JAR_TMP)/% : $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
$(install-file) $(install-file)
US_EXPORT_POLICY_JAR_DEPS := $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy US_EXPORT_POLICY_JAR_DEPS := $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
$(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR,$(US_EXPORT_POLICY_JAR_DEPS),\ $(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR,$(US_EXPORT_POLICY_JAR_DEPS),\
SRCS:=$(US_EXPORT_POLICY_JAR_TMP), \ SRCS:=$(US_EXPORT_POLICY_JAR_TMP), \
SUFFIXES:= .policy,\ SUFFIXES:= .policy,\
JAR:=$(US_EXPORT_POLICY_JAR_UNSIGNED), \ JAR:=$(US_EXPORT_POLICY_JAR_UNSIGNED), \
EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
SKIP_METAINF := true)) SKIP_METAINF := true))
JARS += $(US_EXPORT_POLICY_JAR_UNSIGNED)
endif
ifndef OPENJDK ifndef OPENJDK
$(US_EXPORT_POLICY_JAR_DST): $(JDK_TOPDIR)/make/closed/tools/crypto/jce/US_export_policy.jar $(US_EXPORT_POLICY_JAR_DST): $(JDK_TOPDIR)/make/closed/tools/crypto/jce/US_export_policy.jar
$(ECHO) $(LOG_INFO) Copying $(@F) $(ECHO) $(LOG_INFO) Copying $(@F)
$(install-file) $(install-file)
else else
$(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNSIGNED) $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNSIGNED)
$(install-file) $(install-file)
endif endif
JARS += $(US_EXPORT_POLICY_JAR_UNSIGNED)
########################################################################################## ##########################################################################################
LOCAL_POLICY_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/security/local_policy.jar LOCAL_POLICY_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/security/local_policy.jar
LOCAL_POLICY_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/local_policy.jar LOCAL_POLICY_JAR_UNSIGNED := $(IMAGES_OUTPUTDIR)/unsigned/local_policy.jar
# ifneq ($(BUILD_CRYPTO),no)
# TODO fix so that SetupArchive does not write files into SRCS #
# then we don't need this extra copying # TODO fix so that SetupArchive does not write files into SRCS
# # then we don't need this extra copying
LOCAL_POLICY_JAR_TMP := $(IMAGES_OUTPUTDIR)/local_policy_jar.tmp #
LOCAL_POLICY_JAR_TMP := $(IMAGES_OUTPUTDIR)/local_policy_jar.tmp
ifeq ($(UNLIMITED_CRYPTO), true) ifeq ($(UNLIMITED_CRYPTO), true)
LOCAL_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/unlimited LOCAL_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/unlimited
LOCAL_POLICY_JAR_DEPS := $(LOCAL_POLICY_JAR_TMP)/default_local.policy LOCAL_POLICY_JAR_DEPS := $(LOCAL_POLICY_JAR_TMP)/default_local.policy
LOCAL_POLICY_JAR_ATTR := Crypto-Strength: unlimited LOCAL_POLICY_JAR_ATTR := Crypto-Strength: unlimited
else else
LOCAL_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/limited LOCAL_POLICY_JAR_SRC_DIR := $(JDK_TOPDIR)/make/javax/crypto/policy/limited
LOCAL_POLICY_JAR_DEPS := $(LOCAL_POLICY_JAR_TMP)/exempt_local.policy \ LOCAL_POLICY_JAR_DEPS := $(LOCAL_POLICY_JAR_TMP)/exempt_local.policy \
$(LOCAL_POLICY_JAR_TMP)/default_local.policy $(LOCAL_POLICY_JAR_TMP)/default_local.policy
LOCAL_POLICY_JAR_ATTR := Crypto-Strength: limited LOCAL_POLICY_JAR_ATTR := Crypto-Strength: limited
endif endif
$(LOCAL_POLICY_JAR_TMP)/% : $(LOCAL_POLICY_JAR_SRC_DIR)/% $(LOCAL_POLICY_JAR_TMP)/% : $(LOCAL_POLICY_JAR_SRC_DIR)/%
$(install-file) $(install-file)
$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR,$(LOCAL_POLICY_JAR_DEPS),\ $(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR,$(LOCAL_POLICY_JAR_DEPS),\
SRCS:=$(LOCAL_POLICY_JAR_TMP),\ SRCS:=$(LOCAL_POLICY_JAR_TMP),\
SUFFIXES:= .policy,\ SUFFIXES:= .policy,\
JAR:=$(LOCAL_POLICY_JAR_UNSIGNED), \ JAR:=$(LOCAL_POLICY_JAR_UNSIGNED), \
EXTRA_MANIFEST_ATTR := $(LOCAL_POLICY_JAR_ATTR), \ EXTRA_MANIFEST_ATTR := $(LOCAL_POLICY_JAR_ATTR), \
SKIP_METAINF := true)) SKIP_METAINF := true))
JARS += $(LOCAL_POLICY_JAR_UNSIGNED)
endif
ifndef OPENJDK ifndef OPENJDK
$(LOCAL_POLICY_JAR_DST): $(JDK_TOPDIR)/make/closed/tools/crypto/jce/local_policy.jar $(LOCAL_POLICY_JAR_DST): $(JDK_TOPDIR)/make/closed/tools/crypto/jce/local_policy.jar
$(ECHO) $(LOG_INFO) Copying $(@F) $(ECHO) $(LOG_INFO) Copying $(@F)
$(install-file) $(install-file)
else else
$(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNSIGNED) $(LOCAL_POLICY_JAR_DST): $(LOCAL_POLICY_JAR_UNSIGNED)
$(install-file) $(install-file)
endif endif
JARS += $(LOCAL_POLICY_JAR_UNSIGNED)
########################################################################################## ##########################################################################################
ifeq ($(OPENJDK_TARGET_OS),windows) ifeq ($(OPENJDK_TARGET_OS),windows)
......
...@@ -36,11 +36,9 @@ ifeq ($(OPENJDK_TARGET_OS), linux) ...@@ -36,11 +36,9 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
ifdef OPENJDK ifdef OPENJDK
GENDATA_FONT_CONFIG_SRC_DIR := \ GENDATA_FONT_CONFIG_SRC_DIR := \
$(JDK_TOPDIR)/src/solaris/classes/sun/awt/fontconfigs $(JDK_TOPDIR)/src/solaris/classes/sun/awt/fontconfigs
GENDATA_FONT_CONFIG_SRC_FILES := \ # This is placeholder for possible fonconfig files which may
fontconfig.properties \ # useful for some highly specialized Linux distributions
fontconfig.SuSE.properties \ GENDATA_FONT_CONFIG_SRC_FILES :=
fontconfig.Ubuntu.properties \
fontconfig.Fedora.properties
else else
GENDATA_FONT_CONFIG_SRC_DIR := \ GENDATA_FONT_CONFIG_SRC_DIR := \
$(JDK_TOPDIR)/src/closed/solaris/classes/sun/awt/fontconfigs $(JDK_TOPDIR)/src/closed/solaris/classes/sun/awt/fontconfigs
......
...@@ -69,6 +69,9 @@ define typesAndBits ...@@ -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 ...@@ -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 ...@@ -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) \
......
...@@ -50,8 +50,6 @@ images:: jre-image jdk-image ...@@ -50,8 +50,6 @@ images:: jre-image jdk-image
overlay-images: jre-overlay-image jdk-overlay-image overlay-images: jre-overlay-image jdk-overlay-image
-include $(CUSTOM_MAKE_DIR)/Images.gmk
# Processing license files from source area to image area # Processing license files from source area to image area
# These will be modified to have the platform specific EOL chars. # These will be modified to have the platform specific EOL chars.
...@@ -774,3 +772,5 @@ endif # Profile ...@@ -774,3 +772,5 @@ endif # Profile
################################################################################ ################################################################################
.PHONY: default images jre-image jdk-image .PHONY: default images jre-image jdk-image
-include $(CUSTOM_MAKE_DIR)/Images.gmk
...@@ -200,6 +200,46 @@ $(INSTALL_LIBRARIES_HERE)/minimal/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz ...@@ -200,6 +200,46 @@ $(INSTALL_LIBRARIES_HERE)/minimal/%.diz : $(INSTALL_LIBRARIES_HERE)/%.diz
$(RM) $(basename $@).debuginfo $(RM) $(basename $@).debuginfo
$(MV) $@.tmp $@ $(MV) $@.tmp $@
####### ##########################################################################################
# Unpack the binary distributions of the crypto classes if they exist.
SEC_FILES_ZIP:=$(JDK_TOPDIR)/make/tools/crypto/sec-bin.zip
SEC_FILES_WIN_ZIP:=$(JDK_TOPDIR)/make/tools/crypto/sec-windows-bin.zip
JGSS_WIN32_FILES_ZIP:=$(JDK_TOPDIR)/make/tools/crypto/jgss-windows-i586-bin.zip
JGSS_WIN64_FILES_ZIP:=$(JDK_TOPDIR)/make/tools/crypto/jgss-windows-x64-bin.zip
define unzip-sec-file
$(ECHO) Unzipping $(<F)
$(MKDIR) -p $(@D)
$(RM) $@
($(CD) $(JDK_OUTPUTDIR) && $(UNZIP) $< > $@.tmp)
$(MV) $@.tmp $@
endef
$(JDK_OUTPUTDIR)/classes/_the.sec-bin.unzipped: $(SEC_FILES_ZIP)
$(call unzip-sec-file)
$(JDK_OUTPUTDIR)/classes/_the.sec-windows-bin.unzipped: $(SEC_FILES_WIN_ZIP)
$(call unzip-sec-file)
$(JDK_OUTPUTDIR)/classes/_the.jgss-windows-i586-bin.unzipped: $(JGSS_WIN32_FILES_ZIP)
$(call unzip-sec-file)
$(JDK_OUTPUTDIR)/classes/_the.jgss-windows-x64-bin.unzipped: $(JGSS_WIN64_FILES_ZIP)
$(call unzip-sec-file)
ifneq ($(wildcard $(SEC_FILES_ZIP)),)
IMPORT_TARGET_FILES += $(JDK_OUTPUTDIR)/classes/_the.sec-bin.unzipped
ifeq ($(OPENJDK_TARGET_OS),windows)
IMPORT_TARGET_FILES += $(JDK_OUTPUTDIR)/classes/_the.sec-windows-bin.unzipped
ifeq ($(OPENJDK_TARGET_CPU),x86)
IMPORT_TARGET_FILES += $(JDK_OUTPUTDIR)/classes/_the.jgss-windows-i586-bin.unzipped
endif
ifeq ($(OPENJDK_TARGET_CPU),x86_64)
IMPORT_TARGET_FILES += $(JDK_OUTPUTDIR)/classes/_the.jgss-windows-x64-bin.unzipped
endif
endif
endif
##########################################################################################
all: $(IMPORT_TARGET_FILES) all: $(IMPORT_TARGET_FILES)
...@@ -40,7 +40,9 @@ $(eval $(call SetupJavaCompiler,GENERATE_OLDBYTECODE,\ ...@@ -40,7 +40,9 @@ $(eval $(call SetupJavaCompiler,GENERATE_OLDBYTECODE,\
$(eval $(call SetupJavaCompiler,GENERATE_JDKBYTECODE,\ $(eval $(call SetupJavaCompiler,GENERATE_JDKBYTECODE,\
JVM:=$(JAVA),\ JVM:=$(JAVA),\
JAVAC:=$(NEW_JAVAC),\ JAVAC:=$(NEW_JAVAC),\
FLAGS:=-bootclasspath $(JDK_OUTPUTDIR)/classes -source 8 -target 8 -encoding ascii -XDignore.symbol.file=true $(DISABLE_WARNINGS),\ FLAGS:=-bootclasspath $(JDK_OUTPUTDIR)/classes -source 8 -target 8 \
-encoding ascii -XDignore.symbol.file=true $(DISABLE_WARNINGS) \
$(GENERATE_JDKBYTECODE_EXTRA_FLAGS),\
SERVER_DIR:=$(SJAVAC_SERVER_DIR),\ SERVER_DIR:=$(SJAVAC_SERVER_DIR),\
SERVER_JVM:=$(SJAVAC_SERVER_JAVA))) SERVER_JVM:=$(SJAVAC_SERVER_JAVA)))
......
# #
# 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 { ...@@ -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;
......
...@@ -130,7 +130,17 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -130,7 +130,17 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
} }
public synchronized int charToGlyph(int unicode) { public synchronized int charToGlyph(int unicode) {
return charToGlyph((char)unicode); if (unicode >= 0x10000) {
int[] glyphs = new int[2];
char[] surrogates = new char[2];
int base = unicode - 0x10000;
surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START);
surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START);
charsToGlyphs(2, surrogates, glyphs);
return glyphs[0];
} else {
return charToGlyph((char)unicode);
}
} }
public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) { public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
...@@ -138,9 +148,9 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -138,9 +148,9 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
} }
public synchronized void charsToGlyphs(int count, int[] unicodes, int[] glyphs) { public synchronized void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
final char[] unicodeChars = new char[count]; for (int i = 0; i < count; i++) {
for (int i = 0; i < count; i++) unicodeChars[i] = (char)unicodes[i]; glyphs[i] = charToGlyph(unicodes[i]);
cache.get(count, unicodeChars, glyphs); };
} }
// This mapper returns either the glyph code, or if the character can be // This mapper returns either the glyph code, or if the character can be
...@@ -166,7 +176,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -166,7 +176,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
firstLayerCache[1] = 1; firstLayerCache[1] = 1;
} }
public int get(final char index) { public synchronized int get(final int index) {
if (index < FIRST_LAYER_SIZE) { if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes // catch common glyphcodes
return firstLayerCache[index]; return firstLayerCache[index];
...@@ -179,12 +189,12 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -179,12 +189,12 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
} }
if (generalCache == null) return 0; if (generalCache == null) return 0;
final Integer value = generalCache.get(new Integer(index)); final Integer value = generalCache.get(index);
if (value == null) return 0; if (value == null) return 0;
return value.intValue(); return value.intValue();
} }
public void put(final char index, final int value) { public synchronized void put(final int index, final int value) {
if (index < FIRST_LAYER_SIZE) { if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes // catch common glyphcodes
firstLayerCache[index] = value; firstLayerCache[index] = value;
...@@ -204,7 +214,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -204,7 +214,7 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
generalCache = new HashMap<Integer, Integer>(); generalCache = new HashMap<Integer, Integer>();
} }
generalCache.put(new Integer(index), new Integer(value)); generalCache.put(index, value);
} }
private class SparseBitShiftingTwoLayerArray { private class SparseBitShiftingTwoLayerArray {
...@@ -220,14 +230,14 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -220,14 +230,14 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
this.secondLayerLength = size >> shift; this.secondLayerLength = size >> shift;
} }
public int get(final char index) { public int get(final int index) {
final int firstIndex = index >> shift; final int firstIndex = index >> shift;
final int[] firstLayerRow = cache[firstIndex]; final int[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) return 0; if (firstLayerRow == null) return 0;
return firstLayerRow[index - (firstIndex * (1 << shift))]; return firstLayerRow[index - (firstIndex * (1 << shift))];
} }
public void put(final char index, final int value) { public void put(final int index, final int value) {
final int firstIndex = index >> shift; final int firstIndex = index >> shift;
int[] firstLayerRow = cache[firstIndex]; int[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) { if (firstLayerRow == null) {
...@@ -237,77 +247,81 @@ public class CCharToGlyphMapper extends CharToGlyphMapper { ...@@ -237,77 +247,81 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
} }
} }
public void get(int count, char[] indicies, int[] values){ public synchronized void get(int count, char[] indicies, int[] values)
{
// "missed" is the count of 'char' that are not mapped.
// Surrogates count for 2.
// unmappedChars is the unique list of these chars.
// unmappedCharIndices is the location in the original array
int missed = 0; int missed = 0;
for(int i = 0; i < count; i++){ char[] unmappedChars = null;
char code = indicies[i]; int [] unmappedCharIndices = null;
for (int i = 0; i < count; i++){
int code = indicies[i];
if (code >= HI_SURROGATE_START &&
code <= HI_SURROGATE_END && i < count - 1)
{
char low = indicies[i + 1];
if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
code = (code - HI_SURROGATE_START) * 0x400 +
low - LO_SURROGATE_START + 0x10000;
}
}
final int value = get(code); final int value = get(code);
if(value != 0){ if (value != 0 && value != -1) {
values[i] = value; values[i] = value;
}else{ if (code >= 0x10000) {
// zero this element out, because the caller does not values[i+1] = INVISIBLE_GLYPH_ID;
// promise to keep it clean i++;
}
} else {
values[i] = 0; values[i] = 0;
put(code, -1);
if (unmappedChars == null) {
// This is likely to be longer than we need,
// but is the simplest and cheapest option.
unmappedChars = new char[indicies.length];
unmappedCharIndices = new int[indicies.length];
}
unmappedChars[missed] = indicies[i];
unmappedCharIndices[missed] = i;
if (code >= 0x10000) { // was a surrogate pair
unmappedChars[++missed] = indicies[++i];
}
missed++; missed++;
} }
} }
if (missed == 0) return; // horray! everything is already cached! if (missed == 0) {
return;
final char[] filteredCodes = new char[missed]; // all index codes requested (partially filled)
final int[] filteredIndicies = new int[missed]; // local indicies into filteredCodes array (totally filled)
// scan, mark, and store the index codes again to send into native
int j = 0;
int dupes = 0;
for (int i = 0; i < count; i++){
if (values[i] != 0L) continue; // already filled
final char code = indicies[i];
// we have already promised to fill this code - this is a dupe
if (get(code) == -1){
filteredIndicies[j] = -1;
dupes++;
j++;
continue;
}
// this is a code we have not obtained before
// mark this one as "promise to get" in the global cache with a -1
final int k = j - dupes;
filteredCodes[k] = code;
put(code, -1);
filteredIndicies[j] = k;
j++;
} }
final int filteredRunLen = j - dupes; final int[] glyphCodes = new int[missed];
final int[] filteredValues = new int[filteredRunLen];
// bulk call to fill in the unmapped code points.
// bulk call to fill in the distinct values nativeCharsToGlyphs(fFont.getNativeFontPtr(),
nativeCharsToGlyphs(fFont.getNativeFontPtr(), filteredRunLen, filteredCodes, filteredValues); missed, unmappedChars, glyphCodes);
// scan the requested list, and fill in values from our for (int m = 0; m < missed; m++){
// distinct code list which has been filled from "getDistinct" int i = unmappedCharIndices[m];
j = 0; int code = unmappedChars[m];
for (int i = 0; i < count; i++){ if (code >= HI_SURROGATE_START &&
if (values[i] != 0L && values[i] != -1L) continue; // already placed code <= HI_SURROGATE_END && m < missed - 1)
{
final int k = filteredIndicies[j]; // index into filteredImages array char low = indicies[m + 1];
final char code = indicies[i]; if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
if(k == -1L){ code = (code - HI_SURROGATE_START) * 0x400 +
// we should have already filled the cache with this value low - LO_SURROGATE_START + 0x10000;
values[i] = get(code); }
}else{ }
// fill the particular code request, and store in the cache values[i] = glyphCodes[m];
final int ptr = filteredValues[k]; put(code, values[i]);
values[i] = ptr; if (code >= 0x10000) {
put(code, ptr); m++;
values[i + 1] = INVISIBLE_GLYPH_ID;
} }
j++;
} }
} }
} }
......
/* /*
* 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 { ...@@ -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);
......
...@@ -86,12 +86,13 @@ public final class HmacPKCS12PBESHA1 extends HmacCore { ...@@ -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");
......
...@@ -42,12 +42,10 @@ import java.security.spec.*; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
......
...@@ -731,10 +731,11 @@ public final class SunJCE extends Provider { ...@@ -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");
......
/*
* 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
{
}
...@@ -26,7 +26,6 @@ ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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;
......
...@@ -28,6 +28,7 @@ package java.lang; ...@@ -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> { ...@@ -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;
} }
/** /**
......
/* /*
* 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; ...@@ -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 { ...@@ -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 { ...@@ -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());
}
}
} }
...@@ -128,8 +128,7 @@ public final class HttpCookie implements Cloneable { ...@@ -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 { ...@@ -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 { ...@@ -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}
*/ */
......
...@@ -377,7 +377,7 @@ public final class HttpURLPermission extends Permission { ...@@ -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;
} }
......
...@@ -25,6 +25,7 @@ ...@@ -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; ...@@ -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;
......
...@@ -115,6 +115,12 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private ...@@ -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) {
......
/*
* 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;
}
}
...@@ -253,6 +253,12 @@ class Direct$Type$Buffer$RW$$BO$ ...@@ -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) {
......
...@@ -139,6 +139,12 @@ class Heap$Type$Buffer$RW$ ...@@ -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())
......
...@@ -77,6 +77,10 @@ class StringCharBuffer // package-private ...@@ -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) {
......
...@@ -30,6 +30,11 @@ package java.nio; ...@@ -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 ...@@ -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 ...@@ -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]
} }
...@@ -82,9 +82,15 @@ import sun.reflect.Reflection; ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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();
......
/* /*
* 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 { ...@@ -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 { ...@@ -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);
} }
/** /**
......
...@@ -180,13 +180,27 @@ public class Hashtable<K,V> ...@@ -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> ...@@ -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;
private int hash(Object k) { /**
if (k instanceof String) { * Return an initial value for the hashSeed, or 0 if the random seed is not
return ((String)k).hash32(); * enabled.
*/
final int initHashSeed() {
if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
return sun.misc.Hashing.randomHashSeed(this);
} }
return 0;
}
int h = hashSeed ^ k.hashCode(); private int hash(Object k) {
return 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> ...@@ -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> ...@@ -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();
......
...@@ -159,7 +159,7 @@ public class IntSummaryStatistics implements IntConsumer { ...@@ -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(),
......
...@@ -55,9 +55,9 @@ import java.io.*; ...@@ -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> ...@@ -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> ...@@ -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> ...@@ -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> ...@@ -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> ...@@ -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++;
} }
/** /**
......
...@@ -171,7 +171,7 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer { ...@@ -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(),
......
...@@ -91,6 +91,7 @@ public interface PrimitiveIterator<T> extends Iterator<T> { ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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);
......
...@@ -394,9 +394,9 @@ public interface Spliterator<T> { ...@@ -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}.
*/ */
......
...@@ -29,14 +29,6 @@ package java.util; ...@@ -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; ...@@ -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}.
*
* @apiNote
* <p>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> * <p>
* A {@code StringJoiner} may be employed to create formatted output from a * A {@code StringJoiner} may be employed to create formatted output from a
* collection using lambda expressions as shown in the following example. * {@link java.util.stream.Stream} using
* {@link java.util.stream.Collectors#toStringJoiner}. For example:
* *
* <pre> {@code * <pre> {@code
* List<Person> people = ... * List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
* String commaSeparatedNames = * String commaSeparatedNumbers = numbers.stream()
* people.map(p -> p.getName()).into(new StringJoiner(", ")).toString(); * .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 {
......
...@@ -187,11 +187,37 @@ public class WeakHashMap<K,V> ...@@ -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 int hashSeed;
/**
* Initialize the hashing mask value.
*/ */
transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this); 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> ...@@ -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> ...@@ -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> ...@@ -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> ...@@ -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> ...@@ -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++];
......
...@@ -128,6 +128,14 @@ import java.util.Locale; ...@@ -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
*/ */
......
...@@ -603,7 +603,7 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> { ...@@ -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
......
...@@ -588,7 +588,7 @@ public interface IntStream extends BaseStream<Integer, IntStream> { ...@@ -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
......
...@@ -588,7 +588,7 @@ public interface LongStream extends BaseStream<Long, LongStream> { ...@@ -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
......
...@@ -754,7 +754,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> { ...@@ -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
......
...@@ -38,7 +38,7 @@ import java.util.function.LongConsumer; ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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> { ...@@ -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
*/ */
......
...@@ -41,7 +41,11 @@ import java.util.function.Supplier; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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
......
...@@ -68,6 +68,14 @@ interface ZipConstants { ...@@ -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
*/ */
......
...@@ -25,8 +25,6 @@ ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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.
*/ */
......
...@@ -46,6 +46,7 @@ import java.util.stream.Stream; ...@@ -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 { ...@@ -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;
......
...@@ -32,6 +32,7 @@ import java.io.PushbackInputStream; ...@@ -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 { ...@@ -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 { ...@@ -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.
if (sz >= 16 && (pos + sz) <= len ) {
e.size = get64(extra, pos);
e.csize = get64(extra, pos + 8);
}
break;
case EXTID_NTFS:
pos += 4; // reserved 4 bytes
if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
break; 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;
} }
off += (sz + 4); break;
default: // unknown tag
} }
off += (sz + 4);
} }
} }
return e; return e;
} }
...@@ -430,27 +450,4 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants { ...@@ -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);
}
} }
...@@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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.
*/ */
......
/*
* 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);
}
}
...@@ -1158,6 +1158,9 @@ public class Cipher { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
/* /*
* 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 { ...@@ -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 { ...@@ -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;
......
/* /*
* 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 { ...@@ -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 { ...@@ -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 {
......
/* /*
* 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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
...@@ -36,6 +36,7 @@ import sun.awt.image.BufImgSurfaceData; ...@@ -36,6 +36,7 @@ import sun.awt.image.BufImgSurfaceData;
import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.java2d.pipe.Region;
/** /**
* MaskFill * MaskFill
...@@ -194,10 +195,13 @@ public class MaskFill extends GraphicsPrimitive ...@@ -194,10 +195,13 @@ public class MaskFill extends GraphicsPrimitive
// REMIND: This is not pretty. It would be nicer if we // REMIND: This is not pretty. It would be nicer if we
// passed a "FillData" object to the Pixel loops, instead // passed a "FillData" object to the Pixel loops, instead
// of a SunGraphics2D parameter... // of a SunGraphics2D parameter...
Region clip = sg2d.clipRegion;
sg2d.clipRegion = null;
int pixel = sg2d.pixel; int pixel = sg2d.pixel;
sg2d.pixel = tmpData.pixelFor(sg2d.getColor()); sg2d.pixel = tmpData.pixelFor(sg2d.getColor());
fillop.FillRect(sg2d, tmpData, 0, 0, w, h); fillop.FillRect(sg2d, tmpData, 0, 0, w, h);
sg2d.pixel = pixel; sg2d.pixel = pixel;
sg2d.clipRegion = clip;
maskop.MaskBlit(tmpData, sData, comp, null, maskop.MaskBlit(tmpData, sData, comp, null,
0, 0, x, y, w, h, 0, 0, x, y, w, h,
......
/*
* 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;
}
}
/*
* 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);
}
/*
* 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;
}
}
/* /*
* 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; ...@@ -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; ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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
......
/* /*
* 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 { ...@@ -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();
......
/* /*
* 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 { ...@@ -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 { ...@@ -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();
......
...@@ -60,9 +60,12 @@ public final class JdpPacketWriter { ...@@ -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);
} }
/** /**
......
...@@ -31,7 +31,42 @@ import java.lang.annotation.RetentionPolicy; ...@@ -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; ...@@ -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 "";
} }
...@@ -24,7 +24,7 @@ ...@@ -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 { ...@@ -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.
......
...@@ -3158,6 +3158,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
} }
......
/* /*
* 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 { ...@@ -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);
} }
......
...@@ -360,6 +360,8 @@ class SummaryTab extends Tab { ...@@ -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,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册