# HG changeset patch # User jlaskey # Date 1379078136 10800 # Node ID be6ca7197e0e40e654b9123863820c8f5f930161 # Parent 528fc8f4281b0a9350f948973435d7bb762a08b3# Parent c53411f89b4cc6997a1da3aaca409440683a7c6b Merge diff -r 528fc8f4281b -r be6ca7197e0e .hgtags --- a/.hgtags Tue Aug 27 16:06:01 2013 -0300 +++ b/.hgtags Fri Sep 13 10:15:36 2013 -0300 @@ -226,3 +226,5 @@ 8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102 e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 +1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 +c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 diff -r 528fc8f4281b -r be6ca7197e0e make/java/java/genlocales.gmk --- a/make/java/java/genlocales.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/java/java/genlocales.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -38,31 +38,31 @@ # only FILES_java and FILES_compiled_properties variables will be picked up # # $(BUILDDIR)/java/util/FILES_java.gmk & $(BUILDDIR)/java/util/FILES_properties.gmk -# contain "sun.util.resources" for US language support +# contain "sun.util.resources" for EN language support include $(BUILDDIR)/java/util/FILES_java.gmk include $(BUILDDIR)/java/util/FILES_properties.gmk -US_Resources_java := $(FILES_java) -US_Resources_properties := $(FILES_compiled_properties) +EN_Resources_java := $(FILES_java) +EN_Resources_properties := $(FILES_compiled_properties) # $(BUILDDIR)/java/text/FILES_java.gmk contains the "sun.text.resources" for -# US language support +# EN language support include $(BUILDDIR)/java/text/base/FILES_java.gmk -US_Resources_java += $(FILES_java) +EN_Resources_java += $(FILES_java) FILES_compiled_properties= # $(BUILDDIR)/sun/text/FILES_java.gmk & $(BUILDDIR)/sun/text/FILES_properties.gmk -# contain both resources for Non-US language support +# contain both resources for Non-EN language support include $(BUILDDIR)/sun/text/FILES_java.gmk include $(BUILDDIR)/sun/text/FILES_properties.gmk -NonUS_Resources_java := $(FILES_java) -NonUS_Resources_properties := $(FILES_compiled_properties) +NonEN_Resources_java := $(FILES_java) +NonEN_Resources_properties := $(FILES_compiled_properties) # Restore the orignal FILES_java & FILES_compiled_properties variables FILES_java := $(FILES_java_orig) @@ -80,30 +80,30 @@ ifeq ($(PLATFORM), macosx) $(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH) - @$(RM) $@.tmp.us $@.tmp.nonus; + @$(RM) $@.tmp.en $@.tmp.nonen; @$(prep-target) - @$(ECHO) $(US_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.us; - @$(ECHO) $(US_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.us; - @$(ECHO) $(NonUS_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonus; - @$(ECHO) $(NonUS_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonus; + @$(ECHO) $(EN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.en; + @$(ECHO) $(EN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.en; + @$(ECHO) $(NonEN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonen; + @$(ECHO) $(NonEN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonen; NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \ - $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \ - $@.tmp.nonus $< $@ - @$(RM) $@.tmp.us $@.tmp.nonus; + $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \ + $@.tmp.nonen $< $@ + @$(RM) $@.tmp.en $@.tmp.nonen; else $(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH) - @$(RM) $@.tmp.us $@.tmp.nonus; + @$(RM) $@.tmp.en $@.tmp.nonen; @$(prep-target) - @$(ECHO) $(subst .properties,'\n',$(US_Resources_properties)) > $@.tmp.us; - @$(ECHO) $(subst .java,'\n',$(US_Resources_java)) >> $@.tmp.us; - @$(ECHO) $(subst .properties,'\n',$(NonUS_Resources_properties)) > $@.tmp.nonus; - @$(ECHO) $(subst .java,'\n',$(NonUS_Resources_java)) >> $@.tmp.nonus; + @$(ECHO) $(subst .properties,'\n',$(EN_Resources_properties)) > $@.tmp.en; + @$(ECHO) $(subst .java,'\n',$(EN_Resources_java)) >> $@.tmp.en; + @$(ECHO) $(subst .properties,'\n',$(NonEN_Resources_properties)) > $@.tmp.nonen; + @$(ECHO) $(subst .java,'\n',$(NonEN_Resources_java)) >> $@.tmp.nonen; NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \ - $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \ - $@.tmp.nonus $< $@ - @$(RM) $@.tmp.us $@.tmp.nonus; + $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \ + $@.tmp.nonen $< $@ + @$(RM) $@.tmp.en $@.tmp.nonen; endif genlocales : $(LocaleDataMetaInfo_Dest) diff -r 528fc8f4281b -r be6ca7197e0e make/java/java/localegen.sh --- a/make/java/java/localegen.sh Tue Aug 27 16:06:01 2013 -0300 +++ b/make/java/java/localegen.sh Fri Sep 13 10:15:36 2013 -0300 @@ -35,11 +35,11 @@ # A list of resource base name list; RESOURCE_NAMES=$1 -# A list of US resources; -US_FILES_LIST=$2 +# A list of EN resources; +EN_FILES_LIST=$2 -# A list of non-US resources; -NONUS_FILES_LIST=$3 +# A list of non-EN resources; +NONEN_FILES_LIST=$3 INPUT_FILE=$4 OUTPUT_FILE=$5 @@ -53,23 +53,23 @@ sed_script="$SED -e \"s@^#warn .*@// -- This file was mechanically generated: Do not edit! -- //@\" " # ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files. -nonusall=" ja-JP-JP th-TH-TH " +nonenall=" ja-JP-JP th-TH-TH " for FILE in $RESOURCE_NAMES do - getlocalelist $FILE $US_FILES_LIST - sed_script=$sed_script"-e \"s@#"$FILE"_USLocales#@$localelist@g\" " - usall=$usall" "$localelist - getlocalelist $FILE $NONUS_FILES_LIST - sed_script=$sed_script"-e \"s@#"$FILE"_NonUSLocales#@$localelist@g\" " - nonusall=$nonusall" "$localelist + getlocalelist $FILE $EN_FILES_LIST + sed_script=$sed_script"-e \"s@#"$FILE"_ENLocales#@$localelist@g\" " + enall=$enall" "$localelist + getlocalelist $FILE $NONEN_FILES_LIST + sed_script=$sed_script"-e \"s@#"$FILE"_NonENLocales#@$localelist@g\" " + nonenall=$nonenall" "$localelist done -usall=`(for LOC in $usall; do echo $LOC;done) |$SORT -u` -nonusall=`(for LOC in $nonusall; do echo $LOC;done) |$SORT -u` +enall=`(for LOC in $enall; do echo $LOC;done) |$SORT -u` +nonenall=`(for LOC in $nonenall; do echo $LOC;done) |$SORT -u` -sed_script=$sed_script"-e \"s@#AvailableLocales_USLocales#@$usall@g\" " -sed_script=$sed_script"-e \"s@#AvailableLocales_NonUSLocales#@$nonusall@g\" " +sed_script=$sed_script"-e \"s@#AvailableLocales_ENLocales#@$enall@g\" " +sed_script=$sed_script"-e \"s@#AvailableLocales_NonENLocales#@$nonenall@g\" " sed_script=$sed_script"$INPUT_FILE > $OUTPUT_FILE" eval $sed_script diff -r 528fc8f4281b -r be6ca7197e0e make/java/text/base/FILES_java.gmk --- a/make/java/text/base/FILES_java.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/java/text/base/FILES_java.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -107,5 +107,17 @@ sun/text/resources/FormatData.java \ sun/text/resources/JavaTimeSupplementary.java \ sun/text/resources/en/FormatData_en.java \ + sun/text/resources/en/FormatData_en_AU.java \ + sun/text/resources/en/FormatData_en_CA.java \ + sun/text/resources/en/FormatData_en_GB.java \ + sun/text/resources/en/FormatData_en_IE.java \ + sun/text/resources/en/FormatData_en_IN.java \ + sun/text/resources/en/FormatData_en_MT.java \ + sun/text/resources/en/FormatData_en_NZ.java \ + sun/text/resources/en/FormatData_en_PH.java \ + sun/text/resources/en/FormatData_en_SG.java \ sun/text/resources/en/FormatData_en_US.java \ + sun/text/resources/en/FormatData_en_ZA.java \ sun/text/resources/en/JavaTimeSupplementary_en.java \ + sun/text/resources/en/JavaTimeSupplementary_en_GB.java \ + sun/text/resources/en/JavaTimeSupplementary_en_SG.java diff -r 528fc8f4281b -r be6ca7197e0e make/java/util/FILES_java.gmk --- a/make/java/util/FILES_java.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/java/util/FILES_java.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -30,4 +30,7 @@ sun/util/resources/LocaleNamesBundle.java \ sun/util/resources/TimeZoneNamesBundle.java \ sun/util/resources/TimeZoneNames.java \ - sun/util/resources/en/TimeZoneNames_en.java + sun/util/resources/en/TimeZoneNames_en.java \ + sun/util/resources/en/TimeZoneNames_en_CA.java \ + sun/util/resources/en/TimeZoneNames_en_GB.java \ + sun/util/resources/en/TimeZoneNames_en_IE.java diff -r 528fc8f4281b -r be6ca7197e0e make/java/util/FILES_properties.gmk --- a/make/java/util/FILES_properties.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/java/util/FILES_properties.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -26,9 +26,25 @@ FILES_compiled_properties = \ sun/util/resources/LocaleNames.properties \ sun/util/resources/en/LocaleNames_en.properties \ + sun/util/resources/en/LocaleNames_en_MT.properties \ + sun/util/resources/en/LocaleNames_en_PH.properties \ + sun/util/resources/en/LocaleNames_en_SG.properties \ \ sun/util/resources/CalendarData.properties \ sun/util/resources/en/CalendarData_en.properties \ + sun/util/resources/en/CalendarData_en_GB.properties \ + sun/util/resources/en/CalendarData_en_IE.properties \ + sun/util/resources/en/CalendarData_en_MT.properties \ \ sun/util/resources/CurrencyNames.properties \ - sun/util/resources/en/CurrencyNames_en_US.properties + sun/util/resources/en/CurrencyNames_en_AU.properties \ + sun/util/resources/en/CurrencyNames_en_CA.properties \ + sun/util/resources/en/CurrencyNames_en_GB.properties \ + sun/util/resources/en/CurrencyNames_en_IE.properties \ + sun/util/resources/en/CurrencyNames_en_IN.properties \ + sun/util/resources/en/CurrencyNames_en_MT.properties \ + sun/util/resources/en/CurrencyNames_en_NZ.properties \ + sun/util/resources/en/CurrencyNames_en_PH.properties \ + sun/util/resources/en/CurrencyNames_en_SG.properties \ + sun/util/resources/en/CurrencyNames_en_US.properties \ + sun/util/resources/en/CurrencyNames_en_ZA.properties diff -r 528fc8f4281b -r be6ca7197e0e make/sun/text/FILES_java.gmk --- a/make/sun/text/FILES_java.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/sun/text/FILES_java.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -96,16 +96,6 @@ sun/text/resources/el/FormatData_el.java \ sun/text/resources/el/FormatData_el_CY.java \ sun/text/resources/el/FormatData_el_GR.java \ - sun/text/resources/en/FormatData_en_AU.java \ - sun/text/resources/en/FormatData_en_CA.java \ - sun/text/resources/en/FormatData_en_GB.java \ - sun/text/resources/en/FormatData_en_IE.java \ - sun/text/resources/en/FormatData_en_IN.java \ - sun/text/resources/en/FormatData_en_MT.java \ - sun/text/resources/en/FormatData_en_NZ.java \ - sun/text/resources/en/FormatData_en_PH.java \ - sun/text/resources/en/FormatData_en_SG.java \ - sun/text/resources/en/FormatData_en_ZA.java \ sun/text/resources/es/FormatData_es.java \ sun/text/resources/es/FormatData_es_BO.java \ sun/text/resources/es/FormatData_es_AR.java \ @@ -214,9 +204,6 @@ sun/util/resources/zh/CurrencyNames_zh_SG.java \ sun/util/resources/zh/LocaleNames_zh_HK.java \ sun/util/resources/de/TimeZoneNames_de.java \ - sun/util/resources/en/TimeZoneNames_en_CA.java \ - sun/util/resources/en/TimeZoneNames_en_GB.java \ - sun/util/resources/en/TimeZoneNames_en_IE.java \ sun/util/resources/es/TimeZoneNames_es.java \ sun/util/resources/fr/TimeZoneNames_fr.java \ sun/util/resources/hi/TimeZoneNames_hi.java \ @@ -237,8 +224,6 @@ sun/text/resources/da/JavaTimeSupplementary_da.java \ sun/text/resources/de/JavaTimeSupplementary_de.java \ sun/text/resources/el/JavaTimeSupplementary_el.java \ - sun/text/resources/en/JavaTimeSupplementary_en_GB.java \ - sun/text/resources/en/JavaTimeSupplementary_en_SG.java \ sun/text/resources/es/JavaTimeSupplementary_es.java \ sun/text/resources/et/JavaTimeSupplementary_et.java \ sun/text/resources/fi/JavaTimeSupplementary_fi.java \ diff -r 528fc8f4281b -r be6ca7197e0e make/sun/text/FILES_properties.gmk --- a/make/sun/text/FILES_properties.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/make/sun/text/FILES_properties.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -33,9 +33,6 @@ sun/util/resources/de/LocaleNames_de.properties \ sun/util/resources/el/LocaleNames_el.properties \ sun/util/resources/el/LocaleNames_el_CY.properties \ - sun/util/resources/en/LocaleNames_en_MT.properties \ - sun/util/resources/en/LocaleNames_en_PH.properties \ - sun/util/resources/en/LocaleNames_en_SG.properties \ sun/util/resources/es/LocaleNames_es.properties \ sun/util/resources/es/LocaleNames_es_US.properties \ sun/util/resources/et/LocaleNames_et.properties \ @@ -88,9 +85,6 @@ sun/util/resources/de/CalendarData_de.properties \ sun/util/resources/el/CalendarData_el.properties \ sun/util/resources/el/CalendarData_el_CY.properties \ - sun/util/resources/en/CalendarData_en_GB.properties \ - sun/util/resources/en/CalendarData_en_IE.properties \ - sun/util/resources/en/CalendarData_en_MT.properties \ sun/util/resources/es/CalendarData_es.properties \ sun/util/resources/es/CalendarData_es_ES.properties \ sun/util/resources/es/CalendarData_es_US.properties \ @@ -164,16 +158,6 @@ sun/util/resources/de/CurrencyNames_de_LU.properties \ sun/util/resources/el/CurrencyNames_el_CY.properties \ sun/util/resources/el/CurrencyNames_el_GR.properties \ - sun/util/resources/en/CurrencyNames_en_AU.properties \ - sun/util/resources/en/CurrencyNames_en_CA.properties \ - sun/util/resources/en/CurrencyNames_en_GB.properties \ - sun/util/resources/en/CurrencyNames_en_IE.properties \ - sun/util/resources/en/CurrencyNames_en_IN.properties \ - sun/util/resources/en/CurrencyNames_en_MT.properties \ - sun/util/resources/en/CurrencyNames_en_NZ.properties \ - sun/util/resources/en/CurrencyNames_en_PH.properties \ - sun/util/resources/en/CurrencyNames_en_SG.properties \ - sun/util/resources/en/CurrencyNames_en_ZA.properties \ sun/util/resources/es/CurrencyNames_es.properties \ sun/util/resources/es/CurrencyNames_es_AR.properties \ sun/util/resources/es/CurrencyNames_es_BO.properties \ diff -r 528fc8f4281b -r be6ca7197e0e makefiles/CopyFiles.gmk --- a/makefiles/CopyFiles.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/makefiles/CopyFiles.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -292,8 +292,11 @@ JVMCFG_DIR := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR) JVMCFG := $(JVMCFG_DIR)/jvm.cfg +# To do: should this also support -zeroshark? -ifeq ($(OPENJDK_TARGET_CPU_BITS),32) +ifeq ($(OPENJDK_TARGET_CPU_BITS),64) + COPY_JVM_CFG_FILE := true +else # On 32-bit machines we have three potential VMs: client, server and minimal. # Historically we usually have both client and server and so that is what the # committed jvm.cfg expects (including platform specific ergonomics switches @@ -302,16 +305,21 @@ # The main problem is deciding whether to use aliases for the VMs that are not # present and the current position is that we add aliases for client and server, but # not for minimal. - # To do: should this also support, -zero and -zeroshark? - CLIENT_AND_SERVER := $(and $(findstring true,$(JVM_VARIANT_SERVER)),$(findstring true,$(JVM_VARIANT_CLIENT))) + ifeq ($(CLIENT_AND_SERVER), true) + COPY_JVM_CFG_FILE := true + else + # For zero, the default jvm.cfg file is sufficient + ifeq ($(JVM_VARIANT_ZERO), true) + COPY_JVM_CFG_FILE := true + endif + endif +endif - ifeq ($(CLIENT_AND_SERVER), true) - # Use the committed jvm.cfg for this 32 bit setup (the minimal - # VM is already KNOWN on platforms that potentially support it) +ifeq ($(COPY_JVM_CFG_FILE), true) $(JVMCFG): $(JVMCFG_SRC) $(call install-file) - else +else $(JVMCFG): $(MKDIR) -p $(@D) $(RM) $(@) @@ -338,12 +346,6 @@ endif endif endif - endif - -else - # Use the default jvm.cfg for this 64 bit setup. - $(JVMCFG): $(JVMCFG_SRC) - $(call install-file) endif COPY_FILES += $(JVMCFG) diff -r 528fc8f4281b -r be6ca7197e0e makefiles/CreateJars.gmk --- a/makefiles/CreateJars.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/makefiles/CreateJars.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -80,39 +80,6 @@ LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/,$(LOCALEDATA_INCLUDE_LOCALES)) \ $(addprefix sun/util/resources/,$(LOCALEDATA_INCLUDE_LOCALES)) -# For non-US English locale data - -LOCALEDATA_INCLUDES += \ - sun/text/resources/en/FormatData_en_AU.class \ - sun/text/resources/en/FormatData_en_CA.class \ - sun/text/resources/en/FormatData_en_GB.class \ - sun/text/resources/en/FormatData_en_IE.class \ - sun/text/resources/en/FormatData_en_IN.class \ - sun/text/resources/en/FormatData_en_MT.class \ - sun/text/resources/en/FormatData_en_NZ.class \ - sun/text/resources/en/FormatData_en_PH.class \ - sun/text/resources/en/FormatData_en_SG.class \ - sun/text/resources/en/FormatData_en_ZA.class \ - sun/util/resources/en/CalendarData_en_GB.class \ - sun/util/resources/en/CalendarData_en_IE.class \ - sun/util/resources/en/CalendarData_en_MT.class \ - sun/util/resources/en/CurrencyNames_en_AU.class \ - sun/util/resources/en/CurrencyNames_en_CA.class \ - sun/util/resources/en/CurrencyNames_en_GB.class \ - sun/util/resources/en/CurrencyNames_en_IE.class \ - sun/util/resources/en/CurrencyNames_en_IN.class \ - sun/util/resources/en/CurrencyNames_en_MT.class \ - sun/util/resources/en/CurrencyNames_en_NZ.class \ - sun/util/resources/en/CurrencyNames_en_PH.class \ - sun/util/resources/en/CurrencyNames_en_SG.class \ - sun/util/resources/en/CurrencyNames_en_ZA.class \ - sun/util/resources/en/LocaleNames_en_MT.class \ - sun/util/resources/en/LocaleNames_en_PH.class \ - sun/util/resources/en/LocaleNames_en_SG.class \ - sun/util/resources/en/TimeZoneNames_en_CA.class \ - sun/util/resources/en/TimeZoneNames_en_GB.class \ - sun/util/resources/en/TimeZoneNames_en_IE.class - $(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR,,\ SRCS:=$(JDK_OUTPUTDIR)/classes,\ SUFFIXES:=.class _dict _th,\ diff -r 528fc8f4281b -r be6ca7197e0e makefiles/GensrcLocaleDataMetaInfo.gmk --- a/makefiles/GensrcLocaleDataMetaInfo.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/makefiles/GensrcLocaleDataMetaInfo.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -50,27 +50,27 @@ $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java) endif -# The US locales -US_LOCALES:=en en-US +# The EN locales +EN_LOCALES:=en% # ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files. -ALL_NON_US_LOCALES:=ja-JP-JP th-TH-TH +ALL_NON_EN_LOCALES:=ja-JP-JP th-TH-TH SED_ARGS:=-e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g' # This macro creates a sed expression that substitues for example: -# #FormatData_USLocales# with: en and/or en_US. +# #FormatData_ENLocales# with: en% locales. define CaptureLocale $1_LOCALES := $$(subst _,-,$$(filter-out $1,$$(subst $1_,,$$(filter $1_%,$(LOCALE_RESOURCES))))) - $1_US_LOCALES := $$(filter $(US_LOCALES),$$($1_LOCALES)) - $1_NON_US_LOCALES := $$(filter-out $(US_LOCALES),$$($1_LOCALES)) + $1_EN_LOCALES := $$(filter $(EN_LOCALES),$$($1_LOCALES)) + $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES),$$($1_LOCALES)) - ALL_US_LOCALES += $$($1_US_LOCALES) - ALL_NON_US_LOCALES += $$($1_NON_US_LOCALES) + ALL_EN_LOCALES += $$($1_EN_LOCALES) + ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES) # Don't sed in a space if there are no locales. - SED_ARGS+= -e 's/$$(HASH)$1_USLocales$$(HASH)/$$(if $$($1_US_LOCALES),$$(SPACE)$$($1_US_LOCALES),)/g' - SED_ARGS+= -e 's/$$(HASH)$1_NonUSLocales$$(HASH)/$$(if $$($1_NON_US_LOCALES),$$(SPACE)$$($1_NON_US_LOCALES),)/g' + SED_ARGS+= -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g' + SED_ARGS+= -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g' endef #sun.text.resources.FormatData @@ -91,8 +91,8 @@ #sun.util.resources.CalendarData $(eval $(call CaptureLocale,CalendarData)) -SED_ARGS+= -e 's/$(HASH)AvailableLocales_USLocales$(HASH)/$(sort $(ALL_US_LOCALES))/g' -SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonUSLocales$(HASH)/$(sort $(ALL_NON_US_LOCALES))/g' +SED_ARGS+= -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g' +SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g' $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java: \ $(JDK_TOPDIR)/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template diff -r 528fc8f4281b -r be6ca7197e0e makefiles/Setup.gmk --- a/makefiles/Setup.gmk Tue Aug 27 16:06:01 2013 -0300 +++ b/makefiles/Setup.gmk Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -25,6 +25,10 @@ DISABLE_WARNINGS:=-Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally +# To build with all warnings enabled, do the following: +# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" +JAVAC_WARNINGS:=-Xlint:-unchecked,-deprecation,-overrides,classfile,dep-ann,divzero,varargs -Werror + # The generate old bytecode javac setup uses the new compiler to compile for the # boot jdk to generate tools that need to be run with the boot jdk. # Thus we force the target bytecode to 7. @@ -41,7 +45,7 @@ JVM:=$(JAVA),\ JAVAC:=$(NEW_JAVAC),\ FLAGS:=-bootclasspath $(JDK_OUTPUTDIR)/classes -source 8 -target 8 \ - -encoding ascii -XDignore.symbol.file=true $(DISABLE_WARNINGS) \ + -encoding ascii -XDignore.symbol.file=true $(JAVAC_WARNINGS) \ $(GENERATE_JDKBYTECODE_EXTRA_FLAGS),\ SERVER_DIR:=$(SJAVAC_SERVER_DIR),\ SERVER_JVM:=$(SJAVAC_SERVER_JAVA))) diff -r 528fc8f4281b -r be6ca7197e0e src/macosx/classes/sun/lwawt/LWToolkit.java --- a/src/macosx/classes/sun/lwawt/LWToolkit.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Sep 13 10:15:36 2013 -0300 @@ -38,6 +38,7 @@ import sun.awt.*; import sun.lwawt.macosx.*; import sun.print.*; +import sun.security.util.SecurityConstants; public abstract class LWToolkit extends SunToolkit implements Runnable { @@ -502,7 +503,7 @@ public Clipboard getSystemClipboard() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { diff -r 528fc8f4281b -r be6ca7197e0e src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java --- a/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Fri Sep 13 10:15:36 2013 -0300 @@ -87,6 +87,7 @@ private int incomingInterruptFD; static { + IOUtil.load(); initStructSizes(); String datamodel = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.arch.data.model") diff -r 528fc8f4281b -r be6ca7197e0e src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java --- a/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Fri Sep 13 10:15:36 2013 -0300 @@ -246,9 +246,4 @@ } return this; } - - - static { - Util.load(); - } } diff -r 528fc8f4281b -r be6ca7197e0e src/share/back/SDE.c --- a/src/share/back/SDE.c Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/back/SDE.c Fri Sep 13 10:15:36 2013 -0300 @@ -28,6 +28,12 @@ #include "util.h" #include "SDE.h" +#ifdef __APPLE__ +/* use setjmp/longjmp versions that do not save/restore the signal mask */ +#define setjmp _setjmp +#define longjmp _longjmp +#endif + /** * This SourceDebugExtension code does not * allow concurrent translation - due to caching method. diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/Association.java --- a/src/share/classes/com/sun/nio/sctp/Association.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/Association.java Fri Sep 13 10:15:36 2013 -0300 @@ -58,6 +58,13 @@ /** * Initializes a new instance of this class. + * + * @param associationID + * The association ID + * @param maxInStreams + * The maximum number of inbound streams + * @param maxOutStreams + * The maximum number of outbound streams */ protected Association(int associationID, int maxInStreams, diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java --- a/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java Fri Sep 13 10:15:36 2013 -0300 @@ -41,6 +41,9 @@ /** * Constructs an instance of this class with the specified message. + * + * @param msg + * The String that contains a detailed message */ public IllegalReceiveException(String msg) { super(msg); diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java --- a/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java Fri Sep 13 10:15:36 2013 -0300 @@ -41,6 +41,9 @@ /** * Constructs an instance of this class with the specified detailed message. + * + * @param msg + * The String that contains a detailed message */ public IllegalUnbindException(String msg) { super(msg); diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/InvalidStreamException.java --- a/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java Fri Sep 13 10:15:36 2013 -0300 @@ -40,6 +40,9 @@ /** * Constructs an instance of this class with the specified detailed message. + * + * @param msg + * The String that contains a detailed message */ public InvalidStreamException(String msg) { super(msg); diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/MessageInfo.java --- a/src/share/classes/com/sun/nio/sctp/MessageInfo.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/MessageInfo.java Fri Sep 13 10:15:36 2013 -0300 @@ -48,7 +48,7 @@ * longer required to be sent after the time period expires. It is not a hard * timeout and may be influenced by whether the association supports the partial * reliability extension, RFC 3758 - * + * . * *

{@code MessageInfo} instances are not safe for use by multiple concurrent * threads. If a MessageInfo is to be used by more than one thread then access diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/Notification.java --- a/src/share/classes/com/sun/nio/sctp/Notification.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/Notification.java Fri Sep 13 10:15:36 2013 -0300 @@ -40,6 +40,8 @@ public interface Notification { /** * Returns the association that this notification is applicable to. + * + * @return The association */ public Association association(); } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/SctpChannel.java --- a/src/share/classes/com/sun/nio/sctp/SctpChannel.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/SctpChannel.java Fri Sep 13 10:15:36 2013 -0300 @@ -59,7 +59,7 @@ * {@link #setOption(SctpSocketOption,Object) setOption} method. An SCTP * channel support the following options: *

- * + *
* * * @@ -636,6 +636,9 @@ /** * Returns the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -659,6 +662,9 @@ /** * Sets the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -752,6 +758,9 @@ * the {@code receive} method of this channel, if it does an * {@link IllegalReceiveException} will be thrown. * + * @param + * The type of the attachment + * * @param dst * The buffer into which message bytes are to be transferred * @@ -831,7 +840,7 @@ * there was insufficient room for the message in the underlying * output buffer * - * @throws InvalidStreamExcepton + * @throws InvalidStreamException * If {@code streamNumner} is negative or greater than or equal to * the maximum number of outgoing streams * diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java --- a/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java Fri Sep 13 10:15:36 2013 -0300 @@ -63,7 +63,7 @@ * {@link #setOption(SctpSocketOption,Object,Association) setOption} method. An * {@code SctpMultiChannel} supports the following options: *
- *
Option NameDescription
+ *
* * * @@ -394,6 +394,9 @@ * Returns all of the remote addresses to which the given association on * this channel's socket is connected. * + * @param association + * The association + * * @return All of the remote addresses for the given association, or * an empty {@code Set} if the association has been shutdown * @@ -431,6 +434,9 @@ * ignored if given. However, if the option is association specific then the * association must be given. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -464,6 +470,9 @@ * ignored if given. However, if the option is association specific then the * association must be given. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -567,6 +576,9 @@ * the {@code receive} method of this channel, if it does an * {@link IllegalReceiveException} will be thrown. * + * @param + * The type of the attachment + * * @param buffer * The buffer into which bytes are to be transferred * @@ -673,7 +685,7 @@ * there was insufficient room for the message in the underlying * output buffer * - * @throws InvalidStreamExcepton + * @throws InvalidStreamException * If {@code streamNumber} is negative, or if an association already * exists and {@code streamNumber} is greater than the maximum number * of outgoing streams diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/com/sun/nio/sctp/SctpServerChannel.java --- a/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java Fri Sep 13 10:15:36 2013 -0300 @@ -47,7 +47,7 @@ * {@link #setOption(SctpSocketOption,Object) setOption} method. SCTP server socket * channels support the following options: *
- *
Option NameDescription
+ *
* * * @@ -345,6 +345,9 @@ /** * Returns the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -367,6 +370,9 @@ /** * Sets the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/awt/TextComponent.java --- a/src/share/classes/java/awt/TextComponent.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/awt/TextComponent.java Fri Sep 13 10:15:36 2013 -0300 @@ -35,6 +35,7 @@ import javax.swing.text.AttributeSet; import javax.accessibility.*; import java.awt.im.InputMethodRequests; +import sun.security.util.SecurityConstants; /** * The TextComponent class is the superclass of @@ -728,7 +729,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm == null) return true; try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); return true; } catch (SecurityException e) {} return false; diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/awt/Toolkit.java --- a/src/share/classes/java/awt/Toolkit.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/awt/Toolkit.java Fri Sep 13 10:15:36 2013 -0300 @@ -1270,12 +1270,8 @@ *

* Each actual implementation of this method should first check if there * is a security manager installed. If there is, the method should call - * the security manager's checkSystemClipboardAccess method - * to ensure it's ok to to access the system clipboard. If the default - * implementation of checkSystemClipboardAccess is used (that - * is, that method is not overriden), then this results in a call to the - * security manager's checkPermission method with an - * AWTPermission("accessClipboard") permission. + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system Clipboard * @exception HeadlessException if GraphicsEnvironment.isHeadless() @@ -1318,14 +1314,9 @@ * system selection Clipboard as described above. *

* Each actual implementation of this method should first check if there - * is a SecurityManager installed. If there is, the method - * should call the SecurityManager's - * checkSystemClipboardAccess method to ensure that client - * code has access the system selection. If the default implementation of - * checkSystemClipboardAccess is used (that is, if the method - * is not overridden), then this results in a call to the - * SecurityManager's checkPermission method with - * an AWTPermission("accessClipboard") permission. + * is a security manager installed. If there is, the method should call + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system selection as a Clipboard, or * null if the native platform does not support a @@ -1699,25 +1690,20 @@ * therefore not assume that the EventQueue instance returned * by this method will be shared by other applets or the system. * - *

First, if there is a security manager, its - * checkAwtEventQueueAccess - * method is called. - * If the default implementation of checkAwtEventQueueAccess - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's checkPermission method - * with an AWTPermission("accessEventQueue") permission. + *

If there is a security manager then its + * {@link SecurityManager#checkPermission checkPermission} method + * is called to check {@code AWTPermission("accessEventQueue")}. * * @return the EventQueue object * @throws SecurityException - * if a security manager exists and its {@link - * java.lang.SecurityManager#checkAwtEventQueueAccess} - * method denies access to the EventQueue + * if a security manager is set and it denies access to + * the {@code EventQueue} * @see java.awt.AWTPermission */ public final EventQueue getSystemEventQueue() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkAwtEventQueueAccess(); + security.checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION); } return getSystemEventQueueImpl(); } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/awt/Window.java --- a/src/share/classes/java/awt/Window.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/awt/Window.java Fri Sep 13 10:15:36 2013 -0300 @@ -195,10 +195,9 @@ /** * This represents the warning message that is * to be displayed in a non secure window. ie : - * a window that has a security manager installed for - * which calling SecurityManager.checkTopLevelWindow() - * is false. This message can be displayed anywhere in - * the window. + * a window that has a security manager installed that denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * This message can be displayed anywhere in the window. * * @serial * @see #getWarningString @@ -417,11 +416,10 @@ * Constructs a new, initially invisible window in default size with the * specified {@code GraphicsConfiguration}. *

- * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager, then it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * to determine whether or not the window must be displayed with + * a warning banner. * * @param gc the {@code GraphicsConfiguration} of the target screen * device. If {@code gc} is {@code null}, the system default @@ -432,7 +430,6 @@ * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window(GraphicsConfiguration gc) { init(gc); @@ -511,25 +508,16 @@ /** * Constructs a new, initially invisible window in the default size. - * - *

First, if there is a security manager, its - * {@code checkTopLevelWindow} - * method is called with {@code this} - * as its argument - * to see if it's ok to display the window without a warning banner. - * If the default implementation of {@code checkTopLevelWindow} - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's {@code checkPermission} method - * with an {@code AWTPermission("showWindowWithoutWarningBanner")} - * permission. It that method raises a SecurityException, - * {@code checkTopLevelWindow} returns false, otherwise it - * returns true. If it returns false, a warning banner is created. + *

+ * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @exception HeadlessException when * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window() throws HeadlessException { GraphicsEnvironment.checkHeadless(); @@ -541,11 +529,10 @@ * {@code Frame} as its owner. The window will not be focusable * unless its owner is showing on the screen. *

- * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @param owner the {@code Frame} to act as owner or {@code null} * if this window has no owner @@ -555,7 +542,6 @@ * {@code GraphicsEnvironment.isHeadless} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing */ public Window(Frame owner) { @@ -570,11 +556,10 @@ * unless its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

- * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a + * warning banner is created. * * @param owner the {@code Window} to act as owner or * {@code null} if this window has no owner @@ -585,7 +570,6 @@ * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing * * @since 1.2 @@ -603,11 +587,10 @@ * its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

- * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. If that + * check fails with a {@code SecurityException} then a warning banner + * is created. * * @param owner the window to act as owner or {@code null} * if this window has no owner @@ -621,7 +604,6 @@ * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see GraphicsConfiguration#getBounds * @see #isShowing * @since 1.3 @@ -1362,10 +1344,9 @@ * Gets the warning string that is displayed with this window. * If this window is insecure, the warning string is displayed * somewhere in the visible area of the window. A window is - * insecure if there is a security manager, and the security - * manager's {@code checkTopLevelWindow} method returns - * {@code false} when this window is passed to it as an - * argument. + * insecure if there is a security manager and the security + * manager denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. *

* If the window is secure, then {@code getWarningString} * returns {@code null}. If the window is insecure, this @@ -1373,7 +1354,6 @@ * {@code awt.appletWarning} * and returns the string value of that property. * @return the warning string for this window. - * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) */ public final String getWarningString() { return warningString; @@ -1383,10 +1363,12 @@ warningString = null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - if (!sm.checkTopLevelWindow(this)) { + try { + sm.checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION); + } catch (SecurityException se) { // make sure the privileged action is only // for getting the property! We don't want the - // above checkTopLevelWindow call to always succeed! + // above checkPermission call to always succeed! warningString = AccessController.doPrivileged( new GetPropertyAction("awt.appletWarning", "Java Applet Window")); diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/awt/event/InputEvent.java --- a/src/share/classes/java/awt/event/InputEvent.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/awt/event/InputEvent.java Fri Sep 13 10:15:36 2013 -0300 @@ -33,6 +33,7 @@ import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; +import sun.security.util.SecurityConstants; /** * The root event class for all component-level input events. @@ -350,7 +351,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); b = true; } catch (SecurityException se) { if (logger.isLoggable(PlatformLogger.Level.FINE)) { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/io/Console.java --- a/src/share/classes/java/io/Console.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/io/Console.java Fri Sep 13 10:15:36 2013 -0300 @@ -124,9 +124,11 @@ * {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)} * on the returned object will not read in characters beyond the line * bound for each invocation, even if the destination buffer has space for - * more characters. A line bound is considered to be any one of a line feed - * ('\n'), a carriage return ('\r'), a carriage return - * followed immediately by a linefeed, or an end of stream. + * more characters. The {@code Reader}'s {@code read} methods may block if a + * line bound has not been entered or reached on the console's input device. + * A line bound is considered to be any one of a line feed ('\n'), + * a carriage return ('\r'), a carriage return followed immediately + * by a linefeed, or an end of stream. * * @return The reader associated with this console */ diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/AutoCloseable.java --- a/src/share/classes/java/lang/AutoCloseable.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/AutoCloseable.java Fri Sep 13 10:15:36 2013 -0300 @@ -26,7 +26,24 @@ package java.lang; /** - * A resource that must be closed when it is no longer needed. + * An object that may hold resources (such as file or socket handles) + * until it is closed. The {@link #close()} method of an {@code AutoCloseable} + * object is called automatically when exiting a {@code + * try}-with-resources block for which the object has been declared in + * the resource specification header. This construction ensures prompt + * release, avoiding resource exhaustion exceptions and errors that + * may otherwise occur. + * + * @apiNote + *

It is possible, and in fact common, for a base class to + * implement AutoCloseable even though not all of its subclasses or + * instances will hold releasable resources. For code that must operate + * in complete generality, or when it is known that the {@code AutoCloseable} + * instance requires resource release, it is recommended to use {@code + * try}-with-resources constructions. However, when using facilities such as + * {@link java.util.stream.Stream} that support both I/O-based and + * non-I/O-based forms, {@code try}-with-resources blocks are in + * general unnecessary when using non-I/O-based forms. * * @author Josh Bloch * @since 1.7 diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/Class.java --- a/src/share/classes/java/lang/Class.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/Class.java Fri Sep 13 10:15:36 2013 -0300 @@ -821,6 +821,10 @@ *

If this object represents a primitive type or void, the method * returns an array of length 0. * + *

If this {@code Class} object represents an array type, the + * interfaces {@code Cloneable} and {@code java.io.Serializable} are + * returned in that order. + * * @return an array of interfaces implemented by this class. */ public Class[] getInterfaces() { @@ -1484,22 +1488,24 @@ /** * Returns an array containing {@code Field} objects reflecting all * the accessible public fields of the class or interface represented by - * this {@code Class} object. The elements in the array returned are - * not sorted and are not in any particular order. This method returns an - * array of length 0 if the class or interface has no accessible public - * fields, or if it represents an array class, a primitive type, or void. + * this {@code Class} object. + * + *

If this {@code Class} object represents a class or interface with no + * no accessible public fields, then this method returns an array of length + * 0. + * + *

If this {@code Class} object represents a class, then this method + * returns the public fields of the class and of all its superclasses. * - *

Specifically, if this {@code Class} object represents a class, - * this method returns the public fields of this class and of all its - * superclasses. If this {@code Class} object represents an - * interface, this method returns the fields of this interface and of all - * its superinterfaces. + *

If this {@code Class} object represents an interface, then this + * method returns the fields of the interface and of all its + * superinterfaces. * - *

The implicit length field for array class is not reflected by this - * method. User code should use the methods of class {@code Array} to - * manipulate arrays. + *

If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. * - *

See The Java Language Specification, sections 8.2 and 8.3. + *

The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing the * public fields @@ -1512,6 +1518,8 @@ * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getFields() throws SecurityException { @@ -1521,23 +1529,33 @@ /** - * Returns an array containing {@code Method} objects reflecting all - * the public member methods of the class or interface represented - * by this {@code Class} object, including those declared by the class - * or interface and those inherited from superclasses and - * superinterfaces. Array classes return all the (public) member methods - * inherited from the {@code Object} class. The elements in the array - * returned are not sorted and are not in any particular order. This - * method returns an array of length 0 if this {@code Class} object - * represents a class or interface that has no public member methods, or if - * this {@code Class} object represents a primitive type or void. + * Returns an array containing {@code Method} objects reflecting all the + * public methods of the class or interface represented by this {@code + * Class} object, including those declared by the class or interface and + * those inherited from superclasses and superinterfaces. + * + *

If this {@code Class} object represents a type that has multiple + * public methods with the same name and parameter types, but different + * return types, then the returned array has a {@code Method} object for + * each such method. + * + *

If this {@code Class} object represents a type with a class + * initialization method {@code }, then the returned array does + * not have a corresponding {@code Method} object. * - *

The class initialization method {@code } is not - * included in the returned array. If the class declares multiple public - * member methods with the same parameter types, they are all included in - * the returned array. + *

If this {@code Class} object represents an array type, then the + * returned array has a {@code Method} object for each of the public + * methods inherited by the array type from {@code Object}. It does not + * contain a {@code Method} object for {@code clone()}. * - *

See The Java Language Specification, sections 8.2 and 8.4. + *

If this {@code Class} object represents a class or interface with no + * public methods, then the returned array has length 0. + * + *

If this {@code Class} object represents a primitive type or void, + * then the returned array has length 0. + * + *

The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Method} objects representing the * public methods of this class @@ -1549,6 +1567,8 @@ * s.checkPackageAccess()} denies access to the package * of this class. * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1595,13 +1615,14 @@ /** - * Returns a {@code Field} object that reflects the specified public - * member field of the class or interface represented by this - * {@code Class} object. The {@code name} parameter is a - * {@code String} specifying the simple name of the desired field. + * Returns a {@code Field} object that reflects the specified public member + * field of the class or interface represented by this {@code Class} + * object. The {@code name} parameter is a {@code String} specifying the + * simple name of the desired field. * *

The field to be reflected is determined by the algorithm that - * follows. Let C be the class represented by this object: + * follows. Let C be the class or interface represented by this object: + * *

    *
  1. If C declares a public field with the name specified, that is the * field to be reflected.
  2. @@ -1614,7 +1635,8 @@ * is thrown. *
* - *

See The Java Language Specification, sections 8.2 and 8.3. + *

If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the field name * @return the {@code Field} object of this class specified by @@ -1631,6 +1653,8 @@ * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getField(String name) @@ -1685,7 +1709,8 @@ * method and the method being overridden would have the same * signature but different return types. * - *

See The Java Language Specification, sections 8.2 and 8.4. + *

If this {@code Class} object represents an array type, then this + * method does not find the {@code clone()} method. * * @param name the name of the method * @param parameterTypes the list of parameters @@ -1702,6 +1727,8 @@ * s.checkPackageAccess()} denies access to the package * of this class. * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1800,12 +1827,15 @@ * declared by the class or interface represented by this * {@code Class} object. This includes public, protected, default * (package) access, and private fields, but excludes inherited fields. - * The elements in the array returned are not sorted and are not in any - * particular order. This method returns an array of length 0 if the class - * or interface declares no fields, or if this {@code Class} object - * represents a primitive type, an array class, or void. + * + *

If this {@code Class} object represents a class or interface with no + * declared fields, then this method returns an array of length 0. * - *

See The Java Language Specification, sections 8.2 and 8.3. + *

If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. + * + *

The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing all the * declared fields of this class @@ -1831,6 +1861,8 @@ * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { @@ -1840,20 +1872,29 @@ /** - * Returns an array of {@code Method} objects reflecting all the - * methods declared by the class or interface represented by this - * {@code Class} object. This includes public, protected, default - * (package) access, and private methods, but excludes inherited methods. - * The elements in the array returned are not sorted and are not in any - * particular order. This method returns an array of length 0 if the class - * or interface declares no methods, or if this {@code Class} object - * represents a primitive type, an array class, or void. The class - * initialization method {@code } is not included in the - * returned array. If the class declares multiple public member methods - * with the same parameter types, they are all included in the returned - * array. + * + * Returns an array containing {@code Method} objects reflecting all the + * declared methods of the class or interface represented by this {@code + * Class} object, including public, protected, default (package) + * access, and private methods, but excluding inherited methods. + * + *

If this {@code Class} object represents a type that has multiple + * declared methods with the same name and parameter types, but different + * return types, then the returned array has a {@code Method} object for + * each such method. * - *

See The Java Language Specification, section 8.2. + *

If this {@code Class} object represents a type that has a class + * initialization method {@code }, then the returned array does + * not have a corresponding {@code Method} object. + * + *

If this {@code Class} object represents a class or interface with no + * declared methods, then the returned array has length 0. + * + *

If this {@code Class} object represents an array type, a primitive + * type, or void, then the returned array has length 0. + * + *

The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Method} objects representing all the * declared methods of this class @@ -1878,6 +1919,8 @@ * * * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1935,9 +1978,11 @@ /** * Returns a {@code Field} object that reflects the specified declared * field of the class or interface represented by this {@code Class} - * object. The {@code name} parameter is a {@code String} that - * specifies the simple name of the desired field. Note that this method - * will not reflect the {@code length} field of an array class. + * object. The {@code name} parameter is a {@code String} that specifies + * the simple name of the desired field. + * + *

If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the name of the field * @return the {@code Field} object for the specified field in this @@ -1967,6 +2012,8 @@ * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getDeclaredField(String name) @@ -1994,6 +2041,9 @@ * name is "<init>"or "<clinit>" a {@code NoSuchMethodException} * is raised. * + *

If this {@code Class} object represents an array type, then this + * method does not find the {@code clone()} method. + * * @param name the name of the method * @param parameterTypes the parameter array * @return the {@code Method} object for the method of this class @@ -2021,6 +2071,8 @@ * * * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/Math.java --- a/src/share/classes/java/lang/Math.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/Math.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -646,7 +646,7 @@ /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

* Special cases: @@ -665,15 +665,37 @@ * @see java.lang.Integer#MIN_VALUE */ public static int round(float a) { - if (a != 0x1.fffffep-2f) // greatest float value less than 0.5 - return (int)floor(a + 0.5f); - else - return 0; + int intBits = Float.floatToRawIntBits(a); + int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) + >> (FloatConsts.SIGNIFICAND_WIDTH - 1); + int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 + + FloatConsts.EXP_BIAS) - biasedExp; + if ((shift & -32) == 0) { // shift >= 0 && shift < 32 + // a is a finite number such that pow(2,-32) <= ulp(a) < 1 + int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) + | (FloatConsts.SIGNIF_BIT_MASK + 1)); + if (intBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (int) a; + } } /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

Special cases: *

  • If the argument is NaN, the result is 0. @@ -692,10 +714,32 @@ * @see java.lang.Long#MIN_VALUE */ public static long round(double a) { - if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5 - return (long)floor(a + 0.5d); - else - return 0; + long longBits = Double.doubleToRawLongBits(a); + long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) + >> (DoubleConsts.SIGNIFICAND_WIDTH - 1); + long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2 + + DoubleConsts.EXP_BIAS) - biasedExp; + if ((shift & -64) == 0) { // shift >= 0 && shift < 64 + // a is a finite number such that pow(2,-64) <= ulp(a) < 1 + long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK) + | (DoubleConsts.SIGNIF_BIT_MASK + 1)); + if (longBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (long) a; + } } private static final class RandomNumberGeneratorHolder { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/ProcessBuilder.java --- a/src/share/classes/java/lang/ProcessBuilder.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/ProcessBuilder.java Fri Sep 13 10:15:36 2013 -0300 @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.AccessControlException; import java.util.Arrays; import java.util.ArrayList; import java.util.List; @@ -1033,9 +1032,9 @@ // Can not disclose the fail reason for read-protected files. try { security.checkRead(prog); - } catch (AccessControlException ace) { + } catch (SecurityException se) { exceptionInfo = ""; - cause = ace; + cause = se; } } // It's much easier for us to create a high-quality error diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/SecurityManager.java --- a/src/share/classes/java/lang/SecurityManager.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/SecurityManager.java Fri Sep 13 10:15:36 2013 -0300 @@ -1336,9 +1336,16 @@ * top-level windows; false otherwise. * @exception NullPointerException if the window argument is * null. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see java.awt.Window * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public boolean checkTopLevelWindow(Object window) { if (window == null) { throw new NullPointerException("window can't be null"); @@ -1398,8 +1405,15 @@ * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the system clipboard. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkSystemClipboardAccess() { Permission perm = SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION; if (perm == null) { @@ -1427,8 +1441,15 @@ * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the AWT event queue. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkAwtEventQueueAccess() { Permission perm = SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION; if (perm == null) { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/StrictMath.java --- a/src/share/classes/java/lang/StrictMath.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/StrictMath.java Fri Sep 13 10:15:36 2013 -0300 @@ -633,7 +633,7 @@ /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

    Special cases: *

    • If the argument is NaN, the result is 0. @@ -656,7 +656,7 @@ /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

      Special cases: *

      • If the argument is NaN, the result is 0. diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/String.java --- a/src/share/classes/java/lang/String.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/String.java Fri Sep 13 10:15:36 2013 -0300 @@ -2457,8 +2457,8 @@ * String message = String.join(" ", strings); * //message returned is: "Java is cool" * - * Set strings = new HashSet<>(); - * Strings.add("Java"); strings.add("is"); + * Set strings = new LinkedHashSet<>(); + * strings.add("Java"); strings.add("is"); * strings.add("very"); strings.add("cool"); * String message = String.join("-", strings); * //message returned is: "Java-is-very-cool" @@ -2652,7 +2652,7 @@ * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the * LATIN SMALL LETTER DOTLESS I character. * To obtain correct results for locale insensitive strings, use - * {@code toLowerCase(Locale.ENGLISH)}. + * {@code toLowerCase(Locale.ROOT)}. *

        * @return the {@code String}, converted to lowercase. * @see java.lang.String#toLowerCase(Locale) @@ -2815,7 +2815,7 @@ * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the * LATIN CAPITAL LETTER I WITH DOT ABOVE character. * To obtain correct results for locale insensitive strings, use - * {@code toUpperCase(Locale.ENGLISH)}. + * {@code toUpperCase(Locale.ROOT)}. *

        * @return the {@code String}, converted to uppercase. * @see java.lang.String#toUpperCase(Locale) diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java --- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Fri Sep 13 10:15:36 2013 -0300 @@ -124,7 +124,7 @@ this.samMethodType = samMethodType; this.implMethod = implMethod; - this.implInfo = new MethodHandleInfo(implMethod); + this.implInfo = caller.revealDirect(implMethod); // @@@ Temporary work-around pending resolution of 8005119 this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial) ? MethodHandleInfo.REF_invokeVirtual diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/InfoFromMemberName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/lang/invoke/InfoFromMemberName.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. 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.lang.invoke; + +import java.security.*; +import java.lang.reflect.*; +import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; + +/* + * Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public. + */ +/*non-public*/ +final +class InfoFromMemberName implements MethodHandleInfo { + private final MemberName member; + private final int referenceKind; + + InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) { + assert(member.isResolved() || member.isMethodHandleInvoke()); + assert(member.referenceKindIsConsistentWith(referenceKind)); + this.member = member; + this.referenceKind = referenceKind; + } + + @Override + public Class getDeclaringClass() { + return member.getDeclaringClass(); + } + + @Override + public String getName() { + return member.getName(); + } + + @Override + public MethodType getMethodType() { + return member.getMethodOrFieldType(); + } + + @Override + public int getModifiers() { + return member.getModifiers(); + } + + @Override + public int getReferenceKind() { + return referenceKind; + } + + @Override + public String toString() { + return MethodHandleInfo.toString(getReferenceKind(), getDeclaringClass(), getName(), getMethodType()); + } + + @Override + public T reflectAs(Class expected, Lookup lookup) { + if (member.isMethodHandleInvoke() && !member.isVarargs()) { + // This member is an instance of a signature-polymorphic method, which cannot be reflected + // A method handle invoker can come in either of two forms: + // A generic placeholder (present in the source code, and varargs) + // and a signature-polymorphic instance (synthetic and not varargs). + // For more information see comments on {@link MethodHandleNatives#linkMethod}. + throw new IllegalArgumentException("cannot reflect signature polymorphic method"); + } + Member mem = AccessController.doPrivileged(new PrivilegedAction() { + public Member run() { + try { + return reflectUnchecked(); + } catch (ReflectiveOperationException ex) { + throw new IllegalArgumentException(ex); + } + } + }); + try { + Class defc = getDeclaringClass(); + byte refKind = (byte) getReferenceKind(); + lookup.checkAccess(refKind, defc, convertToMemberName(refKind, mem)); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + return expected.cast(mem); + } + + private Member reflectUnchecked() throws ReflectiveOperationException { + byte refKind = (byte) getReferenceKind(); + Class defc = getDeclaringClass(); + boolean isPublic = Modifier.isPublic(getModifiers()); + if (MethodHandleNatives.refKindIsMethod(refKind)) { + if (isPublic) + return defc.getMethod(getName(), getMethodType().parameterArray()); + else + return defc.getDeclaredMethod(getName(), getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsConstructor(refKind)) { + if (isPublic) + return defc.getConstructor(getMethodType().parameterArray()); + else + return defc.getDeclaredConstructor(getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsField(refKind)) { + if (isPublic) + return defc.getField(getName()); + else + return defc.getDeclaredField(getName()); + } else { + throw new IllegalArgumentException("referenceKind="+refKind); + } + } + + private static MemberName convertToMemberName(byte refKind, Member mem) throws IllegalAccessException { + if (mem instanceof Method) { + boolean wantSpecial = (refKind == REF_invokeSpecial); + return new MemberName((Method) mem, wantSpecial); + } else if (mem instanceof Constructor) { + return new MemberName((Constructor) mem); + } else if (mem instanceof Field) { + boolean isSetter = (refKind == REF_putField || refKind == REF_putStatic); + return new MemberName((Field) mem, isSetter); + } + throw new InternalError(mem.getClass().getName()); + } +} diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 13 10:15:36 2013 -0300 @@ -612,6 +612,12 @@ return false; // inner class of some sort if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) return false; // not on BCP + MethodType mtype = member.getMethodOrFieldType(); + if (!isStaticallyNameable(mtype.returnType())) + return false; + for (Class ptype : mtype.parameterArray()) + if (!isStaticallyNameable(ptype)) + return false; if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) return true; // in java.lang.invoke package if (member.isPublic() && isStaticallyNameable(cls)) diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/Invokers.java --- a/src/share/classes/java/lang/invoke/Invokers.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/Invokers.java Fri Sep 13 10:15:36 2013 -0300 @@ -87,6 +87,7 @@ lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype)); assert(checkInvoker(invoker)); exactInvoker = invoker; return invoker; @@ -110,6 +111,7 @@ lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype)); assert(checkInvoker(invoker)); generalInvoker = invoker; return invoker; diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MemberName.java --- a/src/share/classes/java/lang/invoke/MemberName.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MemberName.java Fri Sep 13 10:15:36 2013 -0300 @@ -320,14 +320,18 @@ /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */ public boolean isMethodHandleInvoke() { - final int bits = Modifier.NATIVE | Modifier.FINAL; + final int bits = MH_INVOKE_MODS; final int negs = Modifier.STATIC; if (testFlags(bits | negs, bits) && clazz == MethodHandle.class) { - return name.equals("invoke") || name.equals("invokeExact"); + return isMethodHandleInvokeName(name); } return false; } + public static boolean isMethodHandleInvokeName(String name) { + return name.equals("invoke") || name.equals("invokeExact"); + } + private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC; /** Utility method to query the modifier flags of this member. */ public boolean isStatic() { @@ -482,12 +486,27 @@ m.getClass(); // NPE check // fill in vmtarget, vmindex while we have m in hand: MethodHandleNatives.init(this, m); + if (clazz == null) { // MHN.init failed + if (m.getDeclaringClass() == MethodHandle.class && + isMethodHandleInvokeName(m.getName())) { + // The JVM did not reify this signature-polymorphic instance. + // Need a special case here. + // See comments on MethodHandleNatives.linkMethod. + MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes()); + int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual); + init(MethodHandle.class, m.getName(), type, flags); + if (isMethodHandleInvoke()) + return; + } + throw new LinkageError(m.toString()); + } assert(isResolved() && this.clazz != null); this.name = m.getName(); if (this.type == null) this.type = new Object[] { m.getReturnType(), m.getParameterTypes() }; if (wantSpecial) { - assert(!isAbstract()) : this; + if (isAbstract()) + throw new AbstractMethodError(this.toString()); if (getReferenceKind() == REF_invokeVirtual) changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual); else if (getReferenceKind() == REF_invokeInterface) @@ -562,6 +581,22 @@ initResolved(true); } + /** + * Create a name for a signature-polymorphic invoker. + * This is a placeholder for a signature-polymorphic instance + * (of MH.invokeExact, etc.) that the JVM does not reify. + * See comments on {@link MethodHandleNatives#linkMethod}. + */ + static MemberName makeMethodHandleInvoke(String name, MethodType type) { + return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC); + } + static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) { + MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual); + mem.flags |= mods; // it's not resolved, but add these modifiers anyway + assert(mem.isMethodHandleInvoke()) : mem; + return mem; + } + // bare-bones constructor; the JVM will fill it in MemberName() { } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MethodHandle.java --- a/src/share/classes/java/lang/invoke/MethodHandle.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MethodHandle.java Fri Sep 13 10:15:36 2013 -0300 @@ -1285,6 +1285,21 @@ } /*non-public*/ + MethodHandle withInternalMemberName(MemberName member) { + if (member != null) { + return MethodHandleImpl.makeWrappedMember(this, member); + } else if (internalMemberName() == null) { + // The required internaMemberName is null, and this MH (like most) doesn't have one. + return this; + } else { + // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH. + MethodHandle result = rebind(); + assert (result.internalMemberName() == null); + return result; + } + } + + /*non-public*/ boolean isInvokeSpecial() { return false; // DMH.Special returns true } @@ -1356,7 +1371,7 @@ MethodHandle rebind() { // Bind 'this' into a new invoker, of the known class BMH. MethodType type2 = type(); - LambdaForm form2 = reinvokerForm(type2.basicType()); + LambdaForm form2 = reinvokerForm(this); // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) } return BoundMethodHandle.bindSingle(type2, form2, this); } @@ -1369,23 +1384,38 @@ /** Create a LF which simply reinvokes a target of the given basic type. * The target MH must override {@link #reinvokerTarget} to provide the target. */ - static LambdaForm reinvokerForm(MethodType mtype) { - mtype = mtype.basicType(); + static LambdaForm reinvokerForm(MethodHandle target) { + MethodType mtype = target.type().basicType(); LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE); if (reinvoker != null) return reinvoker; - MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype); + if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY) + return makeReinvokerForm(target.type(), target); // cannot cache this + reinvoker = makeReinvokerForm(mtype, null); + return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker); + } + private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) { + boolean customized = (customTargetOrNull != null); + MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype); final int THIS_BMH = 0; final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; - final int NEXT_MH = nameCursor++; + final int NEXT_MH = customized ? -1 : nameCursor++; final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); - names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); - Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); - targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH - names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs); - return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names)); + Object[] targetArgs; + MethodHandle targetMH; + if (customized) { + targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); + targetMH = customTargetOrNull; + } else { + names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); + targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); + targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH + targetMH = MethodHandles.basicInvoker(mtype); + } + names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs); + return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names); } private static final LambdaForm.NamedFunction NF_reinvokerTarget; diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Sep 13 10:15:36 2013 -0300 @@ -317,7 +317,7 @@ private MethodHandle cache; AsVarargsCollector(MethodHandle target, MethodType type, Class arrayType) { - super(type, reinvokerForm(type)); + super(type, reinvokerForm(target)); this.target = target; this.arrayType = arrayType; this.cache = target.asCollector(arrayType, 0); @@ -778,16 +778,27 @@ } static Empty throwException(T t) throws T { throw t; } - static MethodHandle FAKE_METHOD_HANDLE_INVOKE; - static - MethodHandle fakeMethodHandleInvoke(MemberName method) { - MethodType type = method.getInvocationType(); - assert(type.equals(MethodType.methodType(Object.class, Object[].class))); - MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE; + static MethodHandle[] FAKE_METHOD_HANDLE_INVOKE = new MethodHandle[2]; + static MethodHandle fakeMethodHandleInvoke(MemberName method) { + int idx; + assert(method.isMethodHandleInvoke()); + switch (method.getName()) { + case "invoke": idx = 0; break; + case "invokeExact": idx = 1; break; + default: throw new InternalError(method.getName()); + } + MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE[idx]; if (mh != null) return mh; - mh = throwException(type.insertParameterTypes(0, UnsupportedOperationException.class)); + MethodType type = MethodType.methodType(Object.class, UnsupportedOperationException.class, + MethodHandle.class, Object[].class); + mh = throwException(type); mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle")); - FAKE_METHOD_HANDLE_INVOKE = mh; + if (!method.getInvocationType().equals(mh.type())) + throw new InternalError(method.toString()); + mh = mh.withInternalMemberName(method); + mh = mh.asVarargsCollector(Object[].class); + assert(method.isVarargs()); + FAKE_METHOD_HANDLE_INVOKE[idx] = mh; return mh; } @@ -821,7 +832,7 @@ MethodHandle vamh = prepareForInvoker(mh); // Cache the result of makeInjectedInvoker once per argument class. MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass); - return restoreToType(bccInvoker.bindTo(vamh), mh.type()); + return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName()); } private static MethodHandle makeInjectedInvoker(Class hostClass) { @@ -876,8 +887,11 @@ } // Undo the adapter effect of prepareForInvoker: - private static MethodHandle restoreToType(MethodHandle vamh, MethodType type) { - return vamh.asCollector(Object[].class, type.parameterCount()).asType(type); + private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) { + MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount()); + mh = mh.asType(type); + mh = mh.withInternalMemberName(member); + return mh; } private static final MethodHandle MH_checkCallerClass; @@ -939,4 +953,41 @@ } } } + + + /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */ + static class WrappedMember extends MethodHandle { + private final MethodHandle target; + private final MemberName member; + + private WrappedMember(MethodHandle target, MethodType type, MemberName member) { + super(type, reinvokerForm(target)); + this.target = target; + this.member = member; + } + + @Override + MethodHandle reinvokerTarget() { + return target; + } + @Override + MemberName internalMemberName() { + return member; + } + @Override + boolean isInvokeSpecial() { + return target.isInvokeSpecial(); + } + @Override + MethodHandle viewAsType(MethodType newType) { + return new WrappedMember(target, newType, member); + } + } + + static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) { + if (member.equals(target.internalMemberName())) + return target; + return new WrappedMember(target, target.type(), member); + } + } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MethodHandleInfo.java --- a/src/share/classes/java/lang/invoke/MethodHandleInfo.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MethodHandleInfo.java Fri Sep 13 10:15:36 2013 -0300 @@ -24,80 +24,246 @@ */ package java.lang.invoke; + +import java.lang.reflect.*; +import java.util.*; import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; /** - * Cracking (reflecting) method handles back into their constituent symbolic parts. + * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts. + * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}. + *

        + * A direct method handle represents a method, constructor, or field without + * any intervening argument bindings or other transformations. + * The method, constructor, or field referred to by a direct method handle is called + * its underlying member. + * Direct method handles may be obtained in any of these ways: + *

          + *
        • By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant. + * (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.) + *
        • By calling one of the Lookup Factory Methods, + * such as {@link Lookup#findVirtual Lookup.findVirtual}, + * to resolve a symbolic reference into a method handle. + * A symbolic reference consists of a class, name string, and type. + *
        • By calling the factory method {@link Lookup#unreflect Lookup.unreflect} + * or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial} + * to convert a {@link Method} into a method handle. + *
        • By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor} + * to convert a {@link Constructor} into a method handle. + *
        • By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter} + * or {@link Lookup#unreflectSetter Lookup.unreflectSetter} + * to convert a {@link Field} into a method handle. + *
        + * In all of these cases, it is possible to crack the resulting direct method handle + * to recover a symbolic reference for the underlying method, constructor, or field. + * Cracking must be done via a {@code Lookup} object equivalent to that which created + * the target method handle, or which has enough access permissions to recreate + * an equivalent method handle. * + *

        Reference kinds

        + * The Lookup Factory Methods + * correspond to all major use cases for methods, constructors, and fields. + * These use cases may be distinguished using small integers as follows: + *
Option NameDescription
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
reference kinddescriptive namescopememberbehavior
{@code 1}{@code REF_getField}{@code class}{@code FT f;}{@code (T) this.f;}
{@code 2}{@code REF_getStatic}{@code class} or {@code interface}{@code static}
{@code FT f;}
{@code (T) C.f;}
{@code 3}{@code REF_putField}{@code class}{@code FT f;}{@code this.f = x;}
{@code 4}{@code REF_putStatic}{@code class}{@code static}
{@code FT f;}
{@code C.f = arg;}
{@code 5}{@code REF_invokeVirtual}{@code class}{@code T m(A*);}{@code (T) this.m(arg*);}
{@code 6}{@code REF_invokeStatic}{@code class} or {@code interface}{@code static}
{@code T m(A*);}
{@code (T) C.m(arg*);}
{@code 7}{@code REF_invokeSpecial}{@code class} or {@code interface}{@code T m(A*);}{@code (T) super.m(arg*);}
{@code 8}{@code REF_newInvokeSpecial}{@code class}{@code C(A*);}{@code new C(arg*);}
{@code 9}{@code REF_invokeInterface}{@code interface}{@code T m(A*);}{@code (T) this.m(arg*);}
+ * @since 1.8 */ -final class MethodHandleInfo { - public static final int - REF_getField = Constants.REF_getField, - REF_getStatic = Constants.REF_getStatic, - REF_putField = Constants.REF_putField, - REF_putStatic = Constants.REF_putStatic, - REF_invokeVirtual = Constants.REF_invokeVirtual, - REF_invokeStatic = Constants.REF_invokeStatic, - REF_invokeSpecial = Constants.REF_invokeSpecial, - REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, - REF_invokeInterface = Constants.REF_invokeInterface; - - private final Class declaringClass; - private final String name; - private final MethodType methodType; - private final int referenceKind; - - public MethodHandleInfo(MethodHandle mh) { - MemberName mn = mh.internalMemberName(); - if (mn == null) throw new IllegalArgumentException("not a direct method handle"); - this.declaringClass = mn.getDeclaringClass(); - this.name = mn.getName(); - this.methodType = mn.getMethodOrFieldType(); - byte refKind = mn.getReferenceKind(); - if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial()) - // Devirtualized method invocation is usually formally virtual. - refKind = REF_invokeVirtual; - this.referenceKind = refKind; - } +public +interface MethodHandleInfo { + /** + * A direct method handle reference kind, + * as defined in the table above. + */ + public static final int + REF_getField = Constants.REF_getField, + REF_getStatic = Constants.REF_getStatic, + REF_putField = Constants.REF_putField, + REF_putStatic = Constants.REF_putStatic, + REF_invokeVirtual = Constants.REF_invokeVirtual, + REF_invokeStatic = Constants.REF_invokeStatic, + REF_invokeSpecial = Constants.REF_invokeSpecial, + REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, + REF_invokeInterface = Constants.REF_invokeInterface; - public Class getDeclaringClass() { - return declaringClass; - } + /** + * Returns the reference kind of the cracked method handle, which in turn + * determines whether the method handle's underlying member was a constructor, method, or field. + * See the table above for definitions. + * @return the integer code for the kind of reference used to access the underlying member + */ + public int getReferenceKind(); - public String getName() { - return name; - } + /** + * Returns the class in which the cracked method handle's underlying member was defined. + * @return the declaring class of the underlying member + */ + public Class getDeclaringClass(); + + /** + * Returns the name of the cracked method handle's underlying member. + * This is {@code "<init>"} if the underlying member was a constructor, + * else it is a simple method name or field name. + * @return the simple name of the underlying member + */ + public String getName(); - public MethodType getMethodType() { - return methodType; - } + /** + * Returns the nominal type of the cracked symbolic reference, expressed as a method type. + * If the reference is to a constructor, the return type will be {@code void}. + * If it is to a non-static method, the method type will not mention the {@code this} parameter. + * If it is to a field and the requested access is to read the field, + * the method type will have no parameters and return the field type. + * If it is to a field and the requested access is to write the field, + * the method type will have one parameter of the field type and return {@code void}. + *

+ * Note that original direct method handle may include a leading {@code this} parameter, + * or (in the case of a constructor) will replace the {@code void} return type + * with the constructed class. + * The nominal type does not include any {@code this} parameter, + * and (in the case of a constructor) will return {@code void}. + * @return the type of the underlying member, expressed as a method type + */ + public MethodType getMethodType(); - public int getModifiers() { - return -1; //TODO - } + // Utility methods. + // NOTE: class/name/type and reference kind constitute a symbolic reference + // member and modifiers are an add-on, derived from Core Reflection (or the equivalent) - public int getReferenceKind() { - return referenceKind; - } + /** + * Reflects the underlying member as a method, constructor, or field object. + * If the underlying member is public, it is reflected as if by + * {@code getMethod}, {@code getConstructor}, or {@code getField}. + * Otherwise, it is reflected as if by + * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}. + * The underlying member must be accessible to the given lookup object. + * @param the desired type of the result, either {@link Member} or a subtype + * @param expected a class object representing the desired result type {@code T} + * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges + * @return a reference to the method, constructor, or field object + * @exception ClassCastException if the member is not of the expected type + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object + */ + public T reflectAs(Class expected, Lookup lookup); - static String getReferenceKindString(int referenceKind) { - switch (referenceKind) { - case REF_getField: return "getfield"; - case REF_getStatic: return "getstatic"; - case REF_putField: return "putfield"; - case REF_putStatic: return "putstatic"; - case REF_invokeVirtual: return "invokevirtual"; - case REF_invokeStatic: return "invokestatic"; - case REF_invokeSpecial: return "invokespecial"; - case REF_newInvokeSpecial: return "newinvokespecial"; - case REF_invokeInterface: return "invokeinterface"; - default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]"; - } + /** + * Returns the access modifiers of the underlying member. + * @return the Java language modifiers for underlying member, + * or -1 if the member cannot be accessed + * @see Modifier + * @see reflectAs + */ + public int getModifiers(); + + /** + * Determines if the underlying member was a variable arity method or constructor. + * Such members are represented by method handles that are varargs collectors. + * @implSpec + * This produces a result equivalent to: + *

{@code
+     *     getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
+     * }
+ * + * + * @return {@code true} if and only if the underlying member was declared with variable arity. + */ + // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector + public default boolean isVarArgs() { + // fields are never varargs: + if (MethodHandleNatives.refKindIsField((byte) getReferenceKind())) + return false; + // not in the public API: Modifier.VARARGS + final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20) + assert(ACC_VARARGS == Modifier.TRANSIENT); + return Modifier.isTransient(getModifiers()); } - @Override - public String toString() { - return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind), - declaringClass.getName(), name, methodType); + /** + * Returns the descriptive name of the given reference kind, + * as defined in the table above. + * The conventional prefix "REF_" is omitted. + * @param referenceKind an integer code for a kind of reference used to access a class member + * @return a mixed-case string such as {@code "getField"} + * @exception IllegalArgumentException if the argument is not a valid + * reference kind number + */ + public static String referenceKindToString(int referenceKind) { + if (!MethodHandleNatives.refKindIsValid(referenceKind)) + throw newIllegalArgumentException("invalid reference kind", referenceKind); + return MethodHandleNatives.refKindName((byte)referenceKind); + } + + /** + * Returns a string representation for a {@code MethodHandleInfo}, + * given the four parts of its symbolic reference. + * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the + * {@linkplain #referenceKindToString reference kind string} for {@code kind}, + * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc} + * {@code N} is the {@code name}, and + * {@code MT} is the {@code type}. + * These four values may be obtained from the + * {@linkplain #getReferenceKind reference kind}, + * {@linkplain #getDeclaringClass declaring class}, + * {@linkplain #getName member name}, + * and {@linkplain #getMethodType method type} + * of a {@code MethodHandleInfo} object. + * + * @implSpec + * This produces a result equivalent to: + *
{@code
+     *     String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
+     * }
+ * + * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference + * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference + * @param name the {@linkplain #getName member name} part of the symbolic reference + * @param type the {@linkplain #getMethodType method type} part of the symbolic reference + * @return a string of the form {@code "RK C.N:MT"} + * @exception IllegalArgumentException if the first argument is not a valid + * reference kind number + * @exception NullPointerException if any reference argument is {@code null} + */ + public static String toString(int kind, Class defc, String name, MethodType type) { + Objects.requireNonNull(name); Objects.requireNonNull(type); + return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type); } } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Sep 13 10:15:36 2013 -0300 @@ -205,6 +205,9 @@ static boolean refKindIsMethod(byte refKind) { return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial); } + static boolean refKindIsConstructor(byte refKind) { + return (refKind == REF_newInvokeSpecial); + } static boolean refKindHasReceiver(byte refKind) { assert(refKindIsValid(refKind)); return (refKind & 1) != 0; @@ -313,7 +316,65 @@ * The method assumes the following arguments on the stack: * 0: the method handle being invoked * 1-N: the arguments to the method handle invocation - * N+1: an implicitly added type argument (the given MethodType) + * N+1: an optional, implicitly added argument (typically the given MethodType) + *

+ * The nominal method at such a call site is an instance of + * a signature-polymorphic method (see @PolymorphicSignature). + * Such method instances are user-visible entities which are + * "split" from the generic placeholder method in {@code MethodHandle}. + * (Note that the placeholder method is not identical with any of + * its instances. If invoked reflectively, is guaranteed to throw an + * {@code UnsupportedOperationException}.) + * If the signature-polymorphic method instance is ever reified, + * it appears as a "copy" of the original placeholder + * (a native final member of {@code MethodHandle}) except + * that its type descriptor has shape required by the instance, + * and the method instance is not varargs. + * The method instance is also marked synthetic, since the + * method (by definition) does not appear in Java source code. + *

+ * The JVM is allowed to reify this method as instance metadata. + * For example, {@code invokeBasic} is always reified. + * But the JVM may instead call {@code linkMethod}. + * If the result is an * ordered pair of a {@code (method, appendix)}, + * the method gets all the arguments (0..N inclusive) + * plus the appendix (N+1), and uses the appendix to complete the call. + * In this way, one reusable method (called a "linker method") + * can perform the function of any number of polymorphic instance + * methods. + *

+ * Linker methods are allowed to be weakly typed, with any or + * all references rewritten to {@code Object} and any primitives + * (except {@code long}/{@code float}/{@code double}) + * rewritten to {@code int}. + * A linker method is trusted to return a strongly typed result, + * according to the specific method type descriptor of the + * signature-polymorphic instance it is emulating. + * This can involve (as necessary) a dynamic check using + * data extracted from the appendix argument. + *

+ * The JVM does not inspect the appendix, other than to pass + * it verbatim to the linker method at every call. + * This means that the JDK runtime has wide latitude + * for choosing the shape of each linker method and its + * corresponding appendix. + * Linker methods should be generated from {@code LambdaForm}s + * so that they do not become visible on stack traces. + *

+ * The {@code linkMethod} call is free to omit the appendix + * (returning null) and instead emulate the required function + * completely in the linker method. + * As a corner case, if N==255, no appendix is possible. + * In this case, the method returned must be custom-generated to + * to perform any needed type checking. + *

+ * If the JVM does not reify a method at a call site, but instead + * calls {@code linkMethod}, the corresponding call represented + * in the bytecodes may mention a valid method which is not + * representable with a {@code MemberName}. + * Therefore, use cases for {@code linkMethod} tend to correspond to + * special cases in reflective code such as {@code findVirtual} + * or {@code revealDirect}. */ static MemberName linkMethod(Class callerClass, int refKind, Class defc, String name, Object type, diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/MethodHandles.java --- a/src/share/classes/java/lang/invoke/MethodHandles.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Fri Sep 13 10:15:36 2013 -0300 @@ -26,8 +26,6 @@ package java.lang.invoke; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.ArrayList; import java.util.Arrays; @@ -54,6 +52,7 @@ * *

* @author John Rose, JSR 292 EG + * @since 1.7 */ public class MethodHandles { @@ -97,6 +96,38 @@ } /** + * Performs an unchecked "crack" of a direct method handle. + * The result is as if the user had obtained a lookup object capable enough + * to crack the target method handle, called + * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect} + * on the target to obtain its symbolic reference, and then called + * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs} + * to resolve the symbolic reference to a member. + *

+ * If there is a security manager, its {@code checkPermission} method + * is called with a {@code ReflectPermission("suppressAccessChecks")} permission. + * @param the desired type of the result, either {@link Member} or a subtype + * @param target a direct method handle to crack into symbolic reference components + * @param expected a class object representing the desired result type {@code T} + * @return a reference to the method, constructor, or field object + * @exception SecurityException if the caller is not privileged to call {@code setAccessible} + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the target is not a direct method handle + * @exception ClassCastException if the member is not of the expected type + * @since 1.8 + */ + public static T + reflectAs(Class expected, MethodHandle target) { + SecurityManager smgr = System.getSecurityManager(); + if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION); + Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup + return lookup.revealDirect(target).reflectAs(expected, lookup); + } + // Copied from AccessibleObject, as used by Method.setAccessible, etc.: + static final private java.security.Permission ACCESS_PERMISSION = + new ReflectPermission("suppressAccessChecks"); + + /** * A lookup object is a factory for creating method handles, * when the creation requires access checking. * Method handles do not perform @@ -647,6 +678,7 @@ return invoker(type); if ("invokeExact".equals(name)) return exactInvoker(type); + assert(!MemberName.isMethodHandleInvokeName(name)); return null; } @@ -892,6 +924,10 @@ * @throws NullPointerException if the argument is null */ public MethodHandle unreflect(Method m) throws IllegalAccessException { + if (m.getDeclaringClass() == MethodHandle.class) { + MethodHandle mh = unreflectForMH(m); + if (mh != null) return mh; + } MemberName method = new MemberName(m); byte refKind = method.getReferenceKind(); if (refKind == REF_invokeSpecial) @@ -900,6 +936,12 @@ Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); } + private MethodHandle unreflectForMH(Method m) { + // these names require special lookups because they throw UnsupportedOperationException + if (MemberName.isMethodHandleInvokeName(m.getName())) + return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m)); + return null; + } /** * Produces a method handle for a reflected method. @@ -1004,6 +1046,46 @@ return unreflectField(f, true); } + /** + * Cracks a direct method handle created by this lookup object or a similar one. + * Security and access checks are performed to ensure that this lookup object + * is capable of reproducing the target method handle. + * This means that the cracking may fail if target is a direct method handle + * but was created by an unrelated lookup object. + * @param target a direct method handle to crack into symbolic reference components + * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object + * @exception SecurityException if a security manager is present and it + * refuses access + * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails + * @exception NullPointerException if the target is {@code null} + * @since 1.8 + */ + public MethodHandleInfo revealDirect(MethodHandle target) { + MemberName member = target.internalMemberName(); + if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke())) + throw newIllegalArgumentException("not a direct method handle"); + Class defc = member.getDeclaringClass(); + byte refKind = member.getReferenceKind(); + assert(MethodHandleNatives.refKindIsValid(refKind)); + if (refKind == REF_invokeSpecial && !target.isInvokeSpecial()) + // Devirtualized method invocation is usually formally virtual. + // To avoid creating extra MemberName objects for this common case, + // we encode this extra degree of freedom using MH.isInvokeSpecial. + refKind = REF_invokeVirtual; + if (refKind == REF_invokeVirtual && defc.isInterface()) + // Symbolic reference is through interface but resolves to Object method (toString, etc.) + refKind = REF_invokeInterface; + // Check SM permissions and member access before cracking. + try { + checkSecurityManager(defc, member); + checkAccess(refKind, defc, member); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + // Produce the handle to the results. + return new InfoFromMemberName(this, member, refKind); + } + /// Helper methods, all package-private. MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { @@ -1201,12 +1283,12 @@ private MethodHandle getDirectMethodCommon(byte refKind, Class refc, MemberName method, boolean doRestrict, Class callerClass) throws IllegalAccessException { checkMethod(refKind, refc, method); - if (method.isMethodHandleInvoke()) - return fakeMethodHandleInvoke(method); + assert(!method.isMethodHandleInvoke()); Class refcAsSuper; if (refKind == REF_invokeSpecial && refc != lookupClass() && + !refc.isInterface() && refc != (refcAsSuper = lookupClass().getSuperclass()) && refc.isAssignableFrom(lookupClass())) { assert(!method.getName().equals("")); // not this code path @@ -1234,9 +1316,6 @@ mh = restrictReceiver(method, mh, lookupClass()); return mh; } - private MethodHandle fakeMethodHandleInvoke(MemberName method) { - return throwException(method.getReturnType(), UnsupportedOperationException.class); - } private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh, Class callerClass) throws IllegalAccessException { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/invoke/SerializedLambda.java --- a/src/share/classes/java/lang/invoke/SerializedLambda.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/invoke/SerializedLambda.java Fri Sep 13 10:15:36 2013 -0300 @@ -225,7 +225,7 @@ @Override public String toString() { - String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind); + String implKind=MethodHandleInfo.referenceKindToString(implMethodKind); return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " + "%s=%s %s.%s:%s, %s=%s, %s=%d]", "capturingClass", capturingClass, diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/lang/reflect/Executable.java --- a/src/share/classes/java/lang/reflect/Executable.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/lang/reflect/Executable.java Fri Sep 13 10:15:36 2013 -0300 @@ -428,20 +428,32 @@ } /** - * Returns an array of arrays that represent the annotations on - * the formal parameters, in declaration order, of the executable - * represented by this object. (Returns an array of length zero if - * the underlying executable is parameterless. If the executable has - * one or more parameters, a nested array of length zero is - * returned for each parameter with no annotations.) The - * annotation objects contained in the returned arrays are - * serializable. The caller of this method is free to modify the - * returned arrays; it will have no effect on the arrays returned - * to other callers. + * Returns an array of arrays of {@code Annotation}s that + * represent the annotations on the formal parameters, in + * declaration order, of the {@code Executable} represented by + * this object. Synthetic and mandated parameters (see + * explanation below), such as the outer "this" parameter to an + * inner class constructor will be represented in the returned + * array. If the executable has no parameters (meaning no formal, + * no synthetic, and no mandated parameters), a zero-length array + * will be returned. If the {@code Executable} has one or more + * parameters, a nested array of length zero is returned for each + * parameter with no annotations. The annotation objects contained + * in the returned arrays are serializable. The caller of this + * method is free to modify the returned arrays; it will have no + * effect on the arrays returned to other callers. * - * @return an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the executable represented by this - * object + * A compiler may add extra parameters that are implicitly + * declared in source ("mandated"), as well as parameters that + * are neither implicitly nor explicitly declared in source + * ("synthetic") to the parameter list for a method. See {@link + * java.lang.reflect.Parameter} for more information. + * + * @see java.lang.reflect.Parameter + * @see java.lang.reflect.Parameter#getAnnotations + * @return an array of arrays that represent the annotations on + * the formal and implicit parameters, in declaration order, of + * the executable represented by this object */ public abstract Annotation[][] getParameterAnnotations(); diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/net/AbstractPlainSocketImpl.java --- a/src/share/classes/java/net/AbstractPlainSocketImpl.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/net/AbstractPlainSocketImpl.java Fri Sep 13 10:15:36 2013 -0300 @@ -719,7 +719,3 @@ public final static int SHUT_RD = 0; public final static int SHUT_WR = 1; } - -class InetAddressContainer { - InetAddress addr; -} diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/net/IDN.java --- a/src/share/classes/java/net/IDN.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/net/IDN.java Fri Sep 13 10:15:36 2013 -0300 @@ -292,13 +292,17 @@ if (useSTD3ASCIIRules) { for (int i = 0; i < dest.length(); i++) { int c = dest.charAt(i); - if (!isLDHChar(c)) { - throw new IllegalArgumentException("Contains non-LDH characters"); + if (isNonLDHAsciiCodePoint(c)) { + throw new IllegalArgumentException( + "Contains non-LDH ASCII characters"); } } - if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') { - throw new IllegalArgumentException("Has leading or trailing hyphen"); + if (dest.charAt(0) == '-' || + dest.charAt(dest.length() - 1) == '-') { + + throw new IllegalArgumentException( + "Has leading or trailing hyphen"); } } @@ -401,26 +405,20 @@ // // LDH stands for "letter/digit/hyphen", with characters restricted to the // 26-letter Latin alphabet , the digits <0-9>, and the hyphen - // <-> - // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x56..0x60, 0x7B..0x7F + // <->. + // Non LDH refers to characters in the ASCII range, but which are not + // letters, digits or the hypen. + // + // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F // - private static boolean isLDHChar(int ch){ - // high runner case - if(ch > 0x007A){ - return false; - } - //['-' '0'..'9' 'A'..'Z' 'a'..'z'] - if((ch == 0x002D) || - (0x0030 <= ch && ch <= 0x0039) || - (0x0041 <= ch && ch <= 0x005A) || - (0x0061 <= ch && ch <= 0x007A) - ){ - return true; - } - return false; + private static boolean isNonLDHAsciiCodePoint(int ch){ + return (0x0000 <= ch && ch <= 0x002C) || + (0x002E <= ch && ch <= 0x002F) || + (0x003A <= ch && ch <= 0x0040) || + (0x005B <= ch && ch <= 0x0060) || + (0x007B <= ch && ch <= 0x007F); } - // // search dots in a string and return the index of that character; // or if there is no dots, return the length of input string diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/net/InetAddressContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/net/InetAddressContainer.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,30 @@ +/* + * 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.net; + +class InetAddressContainer { + InetAddress addr; +} diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/nio/file/Files.java --- a/src/share/classes/java/nio/file/Files.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/nio/file/Files.java Fri Sep 13 10:15:36 2013 -0300 @@ -25,34 +25,56 @@ package java.nio.file; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; -import java.nio.file.spi.FileTypeDetector; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.io.Writer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; -import java.io.Closeable; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.*; -import java.util.function.BiPredicate; -import java.util.stream.CloseableStream; -import java.util.stream.DelegatingStream; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.DosFileAttributes; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileOwnerAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.PosixFileAttributeView; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.spi.FileTypeDetector; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.BiPredicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * This class consists exclusively of static methods that operate on files, @@ -74,6 +96,21 @@ return path.getFileSystem().provider(); } + /** + * Convert a Closeable to a Runnable by converting checked IOException + * to UncheckedIOException + */ + private static Runnable asUncheckedRunnable(Closeable c) { + return () -> { + try { + c.close(); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } + }; + } + // -- File contents -- /** @@ -3228,29 +3265,7 @@ // -- Stream APIs -- /** - * Implementation of CloseableStream - */ - private static class DelegatingCloseableStream extends DelegatingStream - implements CloseableStream - { - private final Closeable closeable; - - DelegatingCloseableStream(Closeable c, Stream delegate) { - super(delegate); - this.closeable = c; - } - - public void close() { - try { - closeable.close(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } - } - - /** - * Return a lazily populated {@code CloseableStream}, the elements of + * Return a lazily populated {@code Stream}, the elements of * which are the entries in the directory. The listing is not recursive. * *

The elements of the stream are {@link Path} objects that are @@ -3264,10 +3279,13 @@ * reflect updates to the directory that occur after returning from this * method. * - *

When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operating on a closed stream behaves as if the end of stream + *

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

Operating on a closed stream behaves as if the end of stream * has been reached. Due to read-ahead, one or more elements may be * returned after the stream has been closed. * @@ -3278,7 +3296,7 @@ * * @param dir The path to the directory * - * @return The {@code CloseableStream} describing the content of the + * @return The {@code Stream} describing the content of the * directory * * @throws NotDirectoryException @@ -3294,43 +3312,54 @@ * @see #newDirectoryStream(Path) * @since 1.8 */ - public static CloseableStream list(Path dir) throws IOException { + public static Stream list(Path dir) throws IOException { DirectoryStream ds = Files.newDirectoryStream(dir); - final Iterator delegate = ds.iterator(); + try { + final Iterator delegate = ds.iterator(); - // Re-wrap DirectoryIteratorException to UncheckedIOException - Iterator it = new Iterator() { - public boolean hasNext() { + // Re-wrap DirectoryIteratorException to UncheckedIOException + Iterator it = new Iterator() { + @Override + public boolean hasNext() { + try { + return delegate.hasNext(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } + } + @Override + public Path next() { + try { + return delegate.next(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } + } + }; + + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false) + .onClose(asUncheckedRunnable(ds)); + } catch (Error|RuntimeException e) { + try { + ds.close(); + } catch (IOException ex) { try { - return delegate.hasNext(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); - } + e.addSuppressed(ex); + } catch (Throwable ignore) {} } - public Path next() { - try { - return delegate.next(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); - } - } - }; - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), - false); - return new DelegatingCloseableStream<>(ds, s); + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link * Path#resolve(Path) resolving} the relative path against {@code start}. * *

The {@code stream} walks the file tree as elements are consumed. - * The {@code CloseableStream} returned is guaranteed to have at least one + * The {@code Stream} returned is guaranteed to have at least one * element, the starting file itself. For each file visited, the stream * attempts to read its {@link BasicFileAttributes}. If the file is a * directory and can be opened successfully, entries in the directory, and @@ -3370,10 +3399,11 @@ *

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

When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operate the stream after it is closed will throw an + *

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

If an {@link IOException} is thrown when accessing the directory @@ -3388,7 +3418,7 @@ * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3401,21 +3431,22 @@ * if an I/O error is thrown when accessing the starting file. * @since 1.8 */ - public static CloseableStream walk(Path start, int maxDepth, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, int maxDepth, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link @@ -3428,12 +3459,19 @@ *

* In other words, it visits all levels of the file tree. * + *

The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an + * {@link java.lang.IllegalStateException}. + * * @param start * the starting file * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws SecurityException * If the security manager denies access to the starting file. @@ -3446,15 +3484,14 @@ * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream walk(Path start, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, + FileVisitOption... options) + throws IOException { return walk(start, Integer.MAX_VALUE, options); } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by searching for files in a file tree rooted at a given starting * file. * @@ -3463,12 +3500,19 @@ * {@link BiPredicate} is invoked with its {@link Path} and {@link * BasicFileAttributes}. The {@code Path} object is obtained as if by * {@link Path#resolve(Path) resolving} the relative path against {@code - * start} and is only included in the returned {@link CloseableStream} if + * start} and is only included in the returned {@link Stream} if * the {@code BiPredicate} returns true. Compare to calling {@link * java.util.stream.Stream#filter filter} on the {@code Stream} * returned by {@code walk} method, this method may be more efficient by * avoiding redundant retrieval of the {@code BasicFileAttributes}. * + *

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

If an {@link IOException} is thrown when accessing the directory * after returned from this method, it is wrapped in an {@link * UncheckedIOException} which will be thrown from the method that caused @@ -3484,7 +3528,7 @@ * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3499,24 +3543,25 @@ * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream find(Path start, - int maxDepth, - BiPredicate matcher, - FileVisitOption... options) - throws IOException - { + public static Stream find(Path start, + int maxDepth, + BiPredicate matcher, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - filter(entry -> matcher.test(entry.file(), entry.attributes())). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .filter(entry -> matcher.test(entry.file(), entry.attributes())) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Read all lines from a file as a {@code CloseableStream}. Unlike {@link + * Read all lines from a file as a {@code Stream}. Unlike {@link * #readAllLines(Path, Charset) readAllLines}, this method does not read * all lines into a {@code List}, but instead populates lazily as the stream * is consumed. @@ -3528,22 +3573,24 @@ *

After this method returns, then any subsequent I/O exception that * occurs while reading from the file or when a malformed or unmappable byte * sequence is read, is wrapped in an {@link UncheckedIOException} that will - * be thrown form the + * be thrown from the * {@link java.util.stream.Stream} method that caused the read to take * place. In case an {@code IOException} is thrown when closing the file, * it is also wrapped as an {@code UncheckedIOException}. * - *

When not using the try-with-resources construct, then stream's - * {@link CloseableStream#close close} method should be invoked after - * operation is completed so as to free any resources held for the open - * file. + *

The returned stream encapsulates a {@link Reader}. If timely + * disposal of file system resources is required, the try-with-resources + * construct should be used to ensure that the stream's + * {@link Stream#close close} method is invoked after the stream operations + * are completed. + * * * @param path * the path to the file * @param cs * the charset to use for decoding * - * @return the lines from the file as a {@code CloseableStream} + * @return the lines from the file as a {@code Stream} * * @throws IOException * if an I/O error occurs opening the file @@ -3557,10 +3604,19 @@ * @see java.io.BufferedReader#lines() * @since 1.8 */ - public static CloseableStream lines(Path path, Charset cs) - throws IOException - { + public static Stream lines(Path path, Charset cs) throws IOException { BufferedReader br = Files.newBufferedReader(path, cs); - return new DelegatingCloseableStream<>(br, br.lines()); + try { + return br.lines().onClose(asUncheckedRunnable(br)); + } catch (Error|RuntimeException e) { + try { + br.close(); + } catch (IOException ex) { + try { + e.addSuppressed(ex); + } catch (Throwable ignore) {} + } + throw e; + } } } diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/Activatable.java --- a/src/share/classes/java/rmi/activation/Activatable.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/Activatable.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,6 +93,8 @@ * @exception RemoteException if either of the following fails: * a) registering the object with the activation system or b) exporting * the object to the RMI runtime. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation. * @since 1.2 **/ protected Activatable(String location, @@ -143,6 +145,8 @@ * @exception RemoteException if either of the following fails: * a) registering the object with the activation system or b) exporting * the object to the RMI runtime. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation. * @since 1.2 **/ protected Activatable(String location, @@ -175,6 +179,8 @@ * @param port the port number on which the object is exported * @exception RemoteException if exporting the object to the RMI * runtime fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected Activatable(ActivationID id, int port) @@ -206,6 +212,8 @@ * @param ssf the server-side socket factory for receiving remote calls * @exception RemoteException if exporting the object to the RMI * runtime fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected Activatable(ActivationID id, int port, @@ -239,6 +247,8 @@ * is not registered with the activation system * @exception ActivationException if activation system is not running * @exception RemoteException if remote call fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote register(ActivationDesc desc) @@ -273,6 +283,8 @@ * already be inactive) * @exception ActivationException if group is not active * @exception RemoteException if call informing monitor fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static boolean inactive(ActivationID id) @@ -290,6 +302,8 @@ * @exception UnknownObjectException if object (id) is unknown * @exception ActivationException if activation system is not running * @exception RemoteException if remote call to activation system fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static void unregister(ActivationID id) @@ -334,6 +348,8 @@ * the wrong group * @exception ActivationException if activation group is not active * @exception RemoteException if object registration or export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 **/ public static ActivationID exportObject(Remote obj, @@ -407,6 +423,8 @@ * descriptor with the activation system * @exception ActivationException if activation group is not active * @exception RemoteException if object registration or export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 **/ public static ActivationID exportObject(Remote obj, @@ -473,6 +491,8 @@ * @param port the port on which the object is exported (an anonymous * port is used if port=0) * @exception RemoteException if object export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote exportObject(Remote obj, @@ -503,6 +523,8 @@ * remote object * @param ssf the server-side socket factory for receiving remote calls * @exception RemoteException if object export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote exportObject(Remote obj, @@ -531,6 +553,8 @@ * @return true if operation is successful, false otherwise * @exception NoSuchObjectException if the remote object is not * currently exported + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static boolean unexportObject(Remote obj, boolean force) diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/ActivationDesc.java --- a/src/share/classes/java/rmi/activation/ActivationDesc.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/ActivationDesc.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,8 @@ * @param data the object's initialization (activation) data contained * in marshalled form. * @exception ActivationException if the current group is nonexistent + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(String className, @@ -142,6 +144,8 @@ * true does not force an initial immediate activation of * a newly registered object; initial activation is lazy. * @exception ActivationException if the current group is nonexistent + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(String className, @@ -176,6 +180,8 @@ * @param data the object's initialization (activation) data contained * in marshalled form. * @exception IllegalArgumentException if groupID is null + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(ActivationGroupID groupID, @@ -208,6 +214,8 @@ * true does not force an initial immediate activation of * a newly registered object; initial activation is lazy. * @exception IllegalArgumentException if groupID is null + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(ActivationGroupID groupID, diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/ActivationGroup.java --- a/src/share/classes/java/rmi/activation/ActivationGroup.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/ActivationGroup.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,8 @@ * * @param groupID the group's identifier * @throws RemoteException if this group could not be exported + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected ActivationGroup(ActivationGroupID groupID) @@ -267,6 +269,8 @@ * (Note: The default implementation of the security manager * checkSetFactory * method requires the RuntimePermission "setFactory") + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see SecurityManager#checkSetFactory * @since 1.2 */ @@ -345,6 +349,8 @@ /** * Returns the current activation group's identifier. Returns null * if no group is currently active for this VM. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @return the activation group's identifier * @since 1.2 */ @@ -394,6 +400,8 @@ * (Note: The default implementation of the security manager * checkSetFactory * method requires the RuntimePermission "setFactory") + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see #getSystem * @see SecurityManager#checkSetFactory * @since 1.2 @@ -428,6 +436,8 @@ * @exception ActivationException if activation system cannot be * obtained or is not bound * (means that it is not running) + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see #setSystem * @since 1.2 */ diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/ActivationGroupID.java --- a/src/share/classes/java/rmi/activation/ActivationGroupID.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/ActivationGroupID.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,8 @@ * Constructs a unique group id. * * @param system the group's activation system + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationGroupID(ActivationSystem system) { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/ActivationID.java --- a/src/share/classes/java/rmi/activation/ActivationID.java Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/ActivationID.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,6 +90,8 @@ * * @param activator reference to the activator responsible for * activating the object + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationID(Activator activator) { diff -r 528fc8f4281b -r be6ca7197e0e src/share/classes/java/rmi/activation/package.html --- a/src/share/classes/java/rmi/activation/package.html Tue Aug 27 16:06:01 2013 -0300 +++ b/src/share/classes/java/rmi/activation/package.html Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ KO!!! "+obj.getClass().getSimpleName()+".hashCode got NPE with a null "+param); + failed++; + } + + try { + obj.toString(); + System.out.println("OK: "+obj.getClass().getSimpleName()+".toString worked with a null "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".toString got NPE."); + failed++; + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanAttributeInfoSupport; +import javax.management.openmbean.OpenMBeanConstructorInfo; +import javax.management.openmbean.OpenMBeanConstructorInfoSupport; +import javax.management.openmbean.OpenMBeanInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenMBeanOperationInfo; +import javax.management.openmbean.OpenMBeanOperationInfoSupport; +import javax.management.openmbean.OpenMBeanParameterInfo; +import javax.management.openmbean.OpenMBeanParameterInfoSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023529 + * @summary Test that OpenMBean*Info.equals do not throw NPE + * @author Shanliang JIANG + * @run clean OpenMBeanInfoEqualsNPETest + * @run build OpenMBeanInfoEqualsNPETest + * @run main OpenMBeanInfoEqualsNPETest + */ +public class OpenMBeanInfoEqualsNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---OpenMBeanInfoEqualsNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on OpenMBeanAttributeInfoSupport..."); + OpenMBeanAttributeInfo openMBeanAttributeInfo0 = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, new Integer[]{1, 2, 3}); + OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3}); + test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "defaultValue"); + + openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, null); + test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "legalValues"); + + // ---- + System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport..."); + OpenMBeanConstructorInfo openMBeanConstructorInfo0 = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, new DescriptorSupport()); + OpenMBeanConstructorInfo openMBeanConstructorInfo; + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", null, new DescriptorSupport()); + test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "sigs"); + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, null); + test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanOperationInfoSupport..."); + OpenMBeanOperationInfo openMBeanOperationInfo0 = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, new DescriptorSupport()); + OpenMBeanOperationInfo openMBeanOperationInfo; + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport()); + test(openMBeanOperationInfo0, openMBeanOperationInfo, "sigs"); + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, MBeanOperationInfo.UNKNOWN, null); + test(openMBeanOperationInfo0, openMBeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1..."); + OpenMBeanParameterInfo openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, 1); + OpenMBeanParameterInfo openMBeanParameterInfo; + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, -1, 1); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, null, 1); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "min value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, null); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "max value"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2..."); + openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2}); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2}); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, null); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "legal values"); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfoSupport..."); + String className = "toto"; + String description = "titi"; + OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{}; + OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{}; + OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + OpenMBeanInfo ominfo0 = new OpenMBeanInfoSupport("toto", description, attrInfos, constrInfos, operaInfos, notifInfos); + OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "class name"); + + ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "description"); + + ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "attrInfos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos); + test(ominfo0, ominfo, "constructor infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos); + test(ominfo0, ominfo, "operation infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null); + test(ominfo0, ominfo, "notif infos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj1, Object obj2, String param) { + try { + obj1.equals(obj2); + System.out.println("OK-1: "+obj1.getClass().getSimpleName()+ + ".equals worked with a null field: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+ + ".equals got NPE with a null field: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj2.equals(obj1); + System.out.println("OK-2: "+obj2.getClass().getSimpleName()+ + ".equals worked with a null field: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+ + ".equals got NPE with a null field: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj1.equals(null); + obj2.equals(null); + + System.out.println("OK-3: "+obj1.getClass().getSimpleName()+ + ".equals worked with a null object."); + } catch (NullPointerException npe) { + System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+ + ".equals got NPE with a null object."); + npe.printStackTrace(); + failed++; + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanNotificationInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanAttributeInfoSupport; +import javax.management.openmbean.OpenMBeanConstructorInfo; +import javax.management.openmbean.OpenMBeanConstructorInfoSupport; +import javax.management.openmbean.OpenMBeanInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenMBeanOperationInfo; +import javax.management.openmbean.OpenMBeanOperationInfoSupport; +import javax.management.openmbean.OpenMBeanParameterInfo; +import javax.management.openmbean.OpenMBeanParameterInfoSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023529 + * @summary Test that OpenMBean*Info.hashCode do not throw NPE + * @author Shanliang JIANG + * @run clean OpenMBeanInfoHashCodeNPETest + * @run build OpenMBeanInfoHashCodeNPETest + * @run main OpenMBeanInfoHashCodeNPETest + */ +public class OpenMBeanInfoHashCodeNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---OpenMBeanInfoHashCodeNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfohashCodeTest..."); + OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3}); + test(openMBeanAttributeInfo, "defaultValue"); + + openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, null); + test(openMBeanAttributeInfo, "legalValues"); + + // ---- + System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport..."); + OpenMBeanConstructorInfo openMBeanConstructorInfo; + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", null, new DescriptorSupport()); + test(openMBeanConstructorInfo, "sigs"); + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, null); + test(openMBeanConstructorInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanOperationInfoSupport..."); + OpenMBeanOperationInfo openMBeanOperationInfo; + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport()); + test(openMBeanOperationInfo, "sigs"); + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, null); + test(openMBeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1..."); + OpenMBeanParameterInfo openMBeanParameterInfo; + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, -1, 1); + test(openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, null, 1); + test(openMBeanParameterInfo, "min value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, null); + test(openMBeanParameterInfo, "max value"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2..."); + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2}); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2}); + test(openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, null); + test(openMBeanParameterInfo, "legal values"); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfoSupport..."); + String className = "toto"; + String description = "titi"; + OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{}; + OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{}; + OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo, "class name"); + + ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo, "description"); + + ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos); + test(ominfo, "attrInfos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos); + test(ominfo, "constructor infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos); + test(ominfo, "operation infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null); + test(ominfo, "notif infos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj, String param) { + try { + obj.hashCode(); + System.out.println("OK-1: "+obj.getClass().getSimpleName()+ + ".hashCode worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+ + ".hashCode got NPE with null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj.toString(); + System.out.println("OK-1: "+obj.getClass().getSimpleName()+ + ".toString worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+ + ".toString got NPE with null paramer: "+param); + npe.printStackTrace(); + failed++; + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXPrincipal; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; +import javax.security.auth.Subject; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's rmbscMap + * @author Shanliang JIANG + * @run clean RMIConnectorInternalMapTest + * @run build RMIConnectorInternalMapTest + * @run main RMIConnectorInternalMapTest + */ + +public class RMIConnectorInternalMapTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorInternalMapTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap"); + rmbscMapField.setAccessible(true); + Map> map = + (Map>) rmbscMapField.get(connectorClient); + if (map != null && !map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time."); + } + + Subject delegationSubject = + new Subject(true, + Collections.singleton(new JMXPrincipal("delegate")), + Collections.EMPTY_SET, + Collections.EMPTY_SET); + MBeanServerConnection mbsc1 = + connectorClient.getMBeanServerConnection(delegationSubject); + MBeanServerConnection mbsc2 = + connectorClient.getMBeanServerConnection(delegationSubject); + + if (mbsc1 == null) { + throw new RuntimeException("Got null connection."); + } + if (mbsc1 != mbsc2) { + throw new RuntimeException("Not got same connection with a same subject."); + } + + map = (Map>) rmbscMapField.get(connectorClient); + if (map == null || map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap has wrong size " + + "after creating a delegated connection."); + } + + delegationSubject = null; + mbsc1 = null; + mbsc2 = null; + + int i = 0; + while (!map.isEmpty() && i++ < 60) { + System.gc(); + Thread.sleep(100); + } + System.out.println("---GC times: " + i); + + if (!map.isEmpty()) { + throw new RuntimeException("Failed to clean RMIConnector's rmbscMap"); + } else { + System.out.println("---RMIConnectorInternalMapTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's nullSubjectConn + * @author Shanliang JIANG + * @run clean RMIConnectorNullSubjectConnTest + * @run build RMIConnectorNullSubjectConnTest + * @run main RMIConnectorNullSubjectConnTest + */ + +public class RMIConnectorNullSubjectConnTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorNullSubjectConnTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field nullSubjectConnField = RMIConnector.class.getDeclaredField("nullSubjectConnRef"); + nullSubjectConnField.setAccessible(true); + + WeakReference weak = + (WeakReference)nullSubjectConnField.get(connectorClient); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("nullSubjectConnRef must be null at initial time."); + } + + MBeanServerConnection conn1 = connectorClient.getMBeanServerConnection(null); + MBeanServerConnection conn2 = connectorClient.getMBeanServerConnection(null); + if (conn1 == null) { + throw new RuntimeException("A connection with null subject should not be null."); + } else if (conn1 != conn2) { + throw new RuntimeException("The 2 connections with null subject are not equal."); + } + + conn1 = null; + conn2 = null; + int i = 1; + do { + System.gc(); + Thread.sleep(100); + weak = (WeakReference)nullSubjectConnField.get(connectorClient); + } while ((weak != null && weak.get() != null) && i++ < 60); + + System.out.println("---GC times: " + i); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("Failed to clean RMIConnector's nullSubjectConn"); + } else { + System.out.println("---RMIConnectorNullSubjectConnTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/jdk/lambda/MethodReferenceTestCallerSensitive.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/lambda/MethodReferenceTestCallerSensitive.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.Test; + +import java.lang.reflect.Field; +import java.util.function.Function; + + +/** + * @author Robert Field + */ + +@Test +public class MethodReferenceTestCallerSensitive { + + private static void getF(T arg) { + Function,Field[]> firstFunction = Class::getFields; + } + + public void testConstructorReferenceVarArgs() { + getF("Hello World"); + } + +} diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/krb5/runNameEquals.sh --- a/test/sun/security/krb5/runNameEquals.sh Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/krb5/runNameEquals.sh Fri Sep 13 10:15:36 2013 -0300 @@ -22,7 +22,7 @@ # # @test -# @bug 6317711 6944847 +# @bug 6317711 6944847 8024046 # @summary Ensure the GSSName has the correct impl which respects # the contract for equals and hashCode across different configurations. @@ -56,6 +56,15 @@ PATHSEP=":" FILESEP="/" NATIVE=true + # Not all *nix has native GSS libs installed + krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + # Fedora has a different path + /usr/kerberos/bin/krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + NATIVE=false + fi + fi ;; CYGWIN* ) PATHSEP=";" diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,17 +21,24 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4969799 * @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't * throw exception - * - * This is making sure that starting a new handshake throws the right - * exception. There is a similar test for SSLSocket. - * + * @run main/othervm CloseEngineException */ +// +// This is making sure that starting a new handshake throws the right +// exception. There is a similar test for SSLSocket. +// + import javax.net.ssl.*; import javax.net.ssl.SSLEngineResult.*; import java.io.*; diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,11 +21,17 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4931274 * @summary closeInbound does not signal when a close_notify has not * been received. + * @run main/othervm CloseInboundException * @author Brad Wetmore */ diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,15 +21,22 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 5019096 * @summary Add scatter/gather APIs for SSLEngine - * - * Check to see if the args are being parsed properly. - * + * @run main/othervm CloseStart */ +// +// Check to see if the args are being parsed properly. +// + import javax.net.ssl.*; import javax.net.ssl.SSLEngineResult.*; import java.io.*; diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,11 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4969459 * @summary Delegated tasks are not reflecting the subclasses of SSLException - * + * @run main/othervm DelegatedTaskWrongException */ import javax.net.ssl.*; diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,10 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 6728126 * @summary Parsing Extensions in Client Hello message is done in a wrong way + * @run main/othervm EmptyExtensionData */ import javax.net.ssl.*; diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,11 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4980882 * @summary SSLEngine should enforce setUseClientMode - * + * @run main/othervm EngineEnforceUseClientMode * @author Brad R. Wetmore */ diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java --- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java Fri Sep 13 10:15:36 2013 -0300 @@ -21,16 +21,21 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 6207322 * @summary SSLEngine is returning a premature FINISHED message when doing - * an abbreviated handshake. + * an abbreviated handshake. * @run main/othervm RehandshakeFinished - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. - * + * @author Brad Wetmore + */ + +/* * This test may need some updating if the messages change order. * Currently I'm expecting that there is a simple renegotiation, with * each message being contained in a single SSL packet. @@ -41,8 +46,6 @@ * FINISHED * CCS * FINISHED - * - * @author Brad Wetmore */ /** diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 7188657 + * @summary There should be a way to reorder the JSSE ciphers + * @run main/othervm UseCipherSuitesOrder + * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA + */ + +import java.io.*; +import java.net.*; +import javax.net.ssl.*; +import java.util.Arrays; + +public class UseCipherSuitesOrder { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Where do we find the keystores? + */ + static String pathToStores = "../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * If the client or server is doing some kind of object creation + * that the other side depends on, and that thread prematurely + * exits, you may experience a hang. The test harness will + * terminate all hung threads after its timeout has expired, + * currently 3 minutes by default, but you might try to be + * smart about it.... + */ + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + // use local cipher suites preference + SSLParameters params = sslServerSocket.getSSLParameters(); + params.setUseCipherSuitesOrder(true); + params.setCipherSuites(srvEnabledCipherSuites); + sslServerSocket.setSSLParameters(params); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + + SSLSession session = sslSocket.getSession(); + if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) { + throw new Exception( + "Expected to negotiate " + srvEnabledCipherSuites[0] + + " , but not " + session.getCipherSuite()); + } + + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLSocketFactory sslsf = + (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocket sslSocket = (SSLSocket) + sslsf.createSocket("localhost", serverPort); + sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + + sslSocket.close(); + } + + // client enabled cipher suites + private static String[] cliEnabledCipherSuites; + + // server enabled cipher suites + private static String[] srvEnabledCipherSuites; + + private static void parseArguments(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Usage: java UseCipherSuitesOrder ciphersuites"); + System.out.println("\tciphersuites: " + + "a list of enabled cipher suites, separated with comma"); + throw new Exception("Incorrect usage"); + } + + cliEnabledCipherSuites = args[0].split(","); + + if (cliEnabledCipherSuites.length < 2) { + throw new Exception("Need to enable at least two cipher suites"); + } + + // Only need to use 2 cipher suites in server side. + srvEnabledCipherSuites = Arrays.copyOf( + cliEnabledCipherSuites, 2); + + // Reverse the cipher suite preference in server side. + srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1]; + srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0]; + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + // parse the arguments + parseArguments(args); + + String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Start the tests. + */ + new UseCipherSuitesOrder(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + UseCipherSuitesOrder() throws Exception { + Exception startException = null; + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + startException = e; + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + if (serverThread != null) { + serverThread.join(); + } + } else { + if (clientThread != null) { + clientThread.join(); + } + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. + */ + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +} diff -r 528fc8f4281b -r be6ca7197e0e test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java --- a/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java Fri Sep 13 10:15:36 2013 -0300 @@ -34,7 +34,7 @@ public static void main(String[] args) throws Exception { String[] illegalNames = { - "example\u3003\u3002com", + "example\u3002\u3002com", "example..com", "com\u3002", "com.", diff -r 528fc8f4281b -r be6ca7197e0e test/sun/tools/jconsole/ImmutableResourceTest.java --- a/test/sun/tools/jconsole/ImmutableResourceTest.java Tue Aug 27 16:06:01 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * - * - * This isn't the test case: ImmutableResourceTest.sh is. - * Refer to ImmutableResourceTest.sh when running this test. - * - * @bug 6287579 - * @summary SubClasses of ListResourceBundle should fix getContents() - */ -import java.util.ResourceBundle; - -public class ImmutableResourceTest { - - public static void main(String[] args) throws Exception { - - /* Reach under the covers and get the message strings */ - sun.tools.jconsole.resources.JConsoleResources jcr = - new sun.tools.jconsole.resources.JConsoleResources (); - Object [][] testData = jcr.getContents(); - - /* Shred our copy of the message strings */ - for (int ii = 0; ii < testData.length; ii++) { - testData[ii][0] = "xxx"; - testData[ii][1] = "yyy"; - } - - /* - * Try a lookup for the shredded key. - * If this is successful we have a problem. - */ - String ss = sun.tools.jconsole.Resources.getText("xxx"); - if ("yyy".equals(ss)) { - throw new Exception ("SubClasses of ListResourceBundle should fix getContents()"); - } - System.out.println("...Finished."); - } -} diff -r 528fc8f4281b -r be6ca7197e0e test/sun/tools/jconsole/ImmutableResourceTest.sh --- a/test/sun/tools/jconsole/ImmutableResourceTest.sh Tue Aug 27 16:06:01 2013 -0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -# -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 6287579 -# @summary SubClasses of ListResourceBundle should fix getContents() -# -# @run shell ImmutableResourceTest.sh - -# Beginning of subroutines: -status=1 - -#Call this from anywhere to fail the test with an error message -# usage: fail "reason why the test failed" -fail() - { echo "The test failed :-(" - echo "$*" 1>&2 - echo "exit status was $status" - exit $status - } #end of fail() - -#Call this from anywhere to pass the test with a message -# usage: pass "reason why the test passed if applicable" -pass() - { echo "The test passed!!!" - echo "$*" 1>&2 - exit 0 - } #end of pass() - -# end of subroutines - -# The beginning of the script proper - -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - PATHSEP=":" - ;; - - Windows* | CYGWIN*) - PATHSEP=";" - ;; - - # catch all other OSs - * ) - echo "Unrecognized system! $OS" - fail "Unrecognized system! $OS" - ;; -esac - -TARGETCLASS="ImmutableResourceTest" -if [ -z "${TESTJAVA}" ] ; then - # TESTJAVA is not set, so the test is running stand-alone. - # TESTJAVA holds the path to the root directory of the build of the JDK - # to be tested. That is, any java files run explicitly in this shell - # should use TESTJAVA in the path to the java interpreter. - # So, we'll set this to the JDK spec'd on the command line. If none - # is given on the command line, tell the user that and use a default. - # THIS IS THE JDK BEING TESTED. - if [ -n "$1" ] ; then - TESTJAVA=$1 - else - TESTJAVA=$JAVA_HOME - fi - TESTSRC=. - TESTCLASSES=. - #Deal with .class files: -fi -# -echo "JDK under test is: $TESTJAVA" -# -CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar" -# Compile the test class using the classpath we need: -# -env -# -set -vx -# -#Compile. jconsole.jar is required on the classpath. -${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \ - "${TESTSRC}"/"${TARGETCLASS}".java -# -#Run the test class, again with the classpath we need: -${TESTJAVA}/bin/java ${CP} ${TARGETCLASS} -status=$? -echo "test status was: $status" -if [ $status -eq "0" ]; - then pass "" - - else fail "unspecified test failure" -fi diff -r 528fc8f4281b -r be6ca7197e0e test/sun/tools/jconsole/ResourceCheckTest.java --- a/test/sun/tools/jconsole/ResourceCheckTest.java Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/tools/jconsole/ResourceCheckTest.java Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,377 +27,134 @@ * This isn't the test case: ResourceCheckTest.sh is. * Refer to ResourceCheckTest.sh when running this test. * - * @bug 5008856 5023573 5024917 5062569 + * @bug 5008856 5023573 5024917 5062569 7172176 * @summary 'missing resource key' error for key = "Operating system" */ -import java.awt.event.KeyEvent; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; +import sun.tools.jconsole.Messages; import sun.tools.jconsole.Resources; +/* + * Ensures that there is a one-to-one mapping between constants in the + * Message class and the keys in the sun.tools.jconsole.resources.messages + * bundle. + * + * An error will be thrown if there is a: + * + * - key in the resource bundle that doesn't have a public static field with + * the same name in the Message class. + * + * - public static field in the Message class that doesn't have a key with + * the same name in the resource bundle. + * + * - message with a mnemonic identifier(&) for which a mnemonic can't + * be looked up using Resources#getMnemonicInt(). + * + */ public class ResourceCheckTest { + private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for"; + private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages"; + private static final String NEW_LINE = String.format("%n"); - public static void main(String[] args){ - Object [][] testData = { - {"<", "", "", "", ""}, - {"<<", "", "", "", ""}, - {">", "", "", "", ""}, - {" 1 day", "", "", "", ""}, - {" 1 hour", "", "", "", ""}, - {" 1 min", "", "", "", ""}, - {" 1 month", "", "", "", ""}, - {" 1 year", "", "", "", ""}, - {" 2 hours", "", "", "", ""}, - {" 3 hours", "", "", "", ""}, - {" 3 months", "", "", "", ""}, - {" 5 min", "", "", "", ""}, - {" 6 hours", "", "", "", ""}, - {" 6 months", "", "", "", ""}, - {" 7 days", "", "", "", ""}, - {"10 min", "", "", "", ""}, - {"12 hours", "", "", "", ""}, - {"30 min", "", "", "", ""}, - {"ACTION", "", "", "", ""}, - {"ACTION_INFO", "", "", "", ""}, - {"All", "", "", "", ""}, - {"Architecture", "", "", "", ""}, - {"Attribute", "", "", "", ""}, - {"Attribute value", "", "", "", ""}, - {"Attribute values", "", "", "", ""}, - {"Attributes", "", "", "", ""}, - {"Blank", "", "", "", ""}, - {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""}, - {"Boot class path", "", "", "", ""}, - {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""}, - {"Close", "", "", "", ""}, - {"CPU Usage", "", "", "", ""}, - {"CPUUsageFormat","PhonyPercentage", "", "", ""}, - {"Cancel", "", "", "", ""}, - {"Cascade", "", "", "", ""}, - {"Cascade.mnemonic", "", "", "", ""}, - {"Chart:", "", "", "", ""}, - {"Chart:.mnemonic", "", "", "", ""}, - {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""}, - {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""}, - {"Class path", "", "", "", ""}, - {"Classes", "", "", "", ""}, - {"ClassName", "", "", "", ""}, - {"Column.Name", "", "", "", ""}, - {"Column.PID", "", "", "", ""}, - {"Committed", "", "", "", ""}, - {"Committed memory", "", "", "", ""}, - {"Committed virtual memory", "", "", "", ""}, - {"Compiler", "", "", "", ""}, - {"Connect...", "", "", "", ""}, - {"Connect", "", "", "", ""}, - {"Connect.mnemonic", "", "", "", ""}, - {"ConnectDialog.connectButton.toolTip", "", "", "", ""}, - {"ConnectDialog.accessibleDescription", "", "", "", ""}, - {"ConnectDialog.masthead.accessibleName", "", "", "", ""}, - {"ConnectDialog.masthead.title", "", "", "", ""}, - {"ConnectDialog.statusBar.accessibleName", "", "", "", ""}, - {"ConnectDialog.title", "", "", "", ""}, - {"Connected. Click to disconnect.", "", "", "", ""}, - {"connectingTo1", "PhonyConnectionName", "", "", ""}, - {"connectingTo2", "PhonyConnectionName", "", "", ""}, - {"connectionFailed1", "", "", "", ""}, - {"connectionFailed2", "PhonyConnectionName", "", "", ""}, - {"connectionLost1", "", "", "", ""}, - {"connectionLost2", "PhonyConnectionName", "", "", ""}, - {"Connection failed", "", "", "", ""}, - {"Connection", "", "", "", ""}, - {"Connection.mnemonic", "", "", "", ""}, - {"Connection name", "", "", "", ""}, - {"ConnectionName (disconnected)", "Phony", "Phony", "", ""}, - {"Constructor", "", "", "", ""}, - {"Create", "Phony", "Phony", "", ""}, - {"Current classes loaded", "", "", "", ""}, - {"Current heap size", "", "", "", ""}, - {"Current value", "PhonyValue", "", "", ""}, - {"Daemon threads", "", "", "", ""}, - {"deadlockAllTab", "", "", "", ""}, - {"deadlockTab", "", "", "", ""}, - {"deadlockTabN", "PhonyInt", "", "", ""}, - {"Description", "", "", "", ""}, - {"Descriptor", "", "", "", ""}, - {"Details", "", "", "", ""}, - {"Detect Deadlock", "", "", "", ""}, - {"Detect Deadlock.mnemonic", "", "", "", ""}, - {"Detect Deadlock.toolTip", "", "", "", ""}, - {"Dimension is not supported:", "", "", "", ""}, - {"Discard chart", "", "", "", ""}, - {"Disconnected. Click to connect.", "", "", "", ""}, - {"Double click to expand/collapse", "", "", "", ""}, - {"Double click to visualize", "", "", "", ""}, - {"DurationDaysHoursMinutes", 0, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1, 13, 54, ""}, - {"DurationDaysHoursMinutes", 2, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1024, 13, 45, ""}, - {"DurationHoursMinutes", 0, 13, "", ""}, - {"DurationHoursMinutes", 1, 0, "", ""}, - {"DurationHoursMinutes", 1, 1, "", ""}, - {"DurationHoursMinutes", 2, 42, "", ""}, - {"DurationMinutes", 0, "", "", ""}, - {"DurationMinutes", 1, "", "", ""}, - {"DurationMinutes", 2, "", "", ""}, - {"DurationSeconds", 0, "", "", ""}, - {"DurationSeconds", 1, "", "", ""}, - {"DurationSeconds", 2, "", "", ""}, - {"Empty array", "", "", "", ""}, - {"Error", "", "", "", ""}, - {"Error: MBeans already exist", "", "", "", ""}, - {"Error: MBeans do not exist", "", "", "", ""}, - {"Event", "", "", "", ""}, - {"Exit", "", "", "", ""}, - {"Exit.mnemonic", "", "", "", ""}, - {"expand", "", "", "", ""}, - {"Fail to load plugin", "", "", "", ""}, - {"FileChooser.fileExists.cancelOption", "", "", "", ""}, - {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""}, - {"FileChooser.fileExists.okOption", "", "", "", ""}, - {"FileChooser.fileExists.title", "", "", "", ""}, - {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""}, - {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""}, - {"FileChooser.saveFailed.title", "", "", "", ""}, - {"Free physical memory", "", "", "", ""}, - {"Free swap space", "", "", "", ""}, - {"Garbage collector", "", "", "", ""}, - {"GC time", "", "", "", ""}, - {"GC time details", 54, "Phony", 11, ""}, - {"GcInfo", "Phony", -1, 768, ""}, - {"GcInfo", "Phony", 0, 768, ""}, - {"GcInfo", "Phony", 1, 768, ""}, - {"Heap", "", "", "", ""}, - {"Heap Memory Usage", "", "", "", ""}, - {"Help.AboutDialog.accessibleDescription", "", "", "", ""}, - {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""}, - {"Help.AboutDialog.masthead.title", "", "", "", ""}, - {"Help.AboutDialog.title", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""}, - {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""}, - {"HelpMenu.About.title", "", "", "", ""}, - {"HelpMenu.About.title.mnemonic", "", "", "", ""}, - {"HelpMenu.UserGuide.title", "", "", "", ""}, - {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""}, - {"HelpMenu.title", "", "", "", ""}, - {"HelpMenu.title.mnemonic", "", "", "", ""}, - {"Hotspot MBeans...", "", "", "", ""}, - {"Hotspot MBeans....mnemonic", "", "", "", ""}, - {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""}, - {"Impact", "", "", "", ""}, - {"Info", "", "", "", ""}, - {"INFO", "", "", "", ""}, - {"Invalid plugin path", "", "", "", ""}, - {"Invalid URL", "", "", "", ""}, - {"Is", "", "", "", ""}, - {"Java Monitoring & Management Console", "", "", "", ""}, - {"Java Virtual Machine", "", "", "", ""}, - {"JConsole: ", "", "", "", ""}, - {"JConsole.accessibleDescription", "", "", "", ""}, - {"JConsole version", "PhonyVersion", "", "", ""}, - {"JIT compiler", "", "", "", ""}, - {"Library path", "", "", "", ""}, - {"Live Threads", "", "", "", ""}, - {"Loaded", "", "", "", ""}, - {"Local Process:", "", "", "", ""}, - {"Local Process:.mnemonic", "", "", "", ""}, - {"Manage Hotspot MBeans in: ", "", "", "", ""}, - {"Management Not Enabled", "", "", "", ""}, - {"Management Will Be Enabled", "", "", "", ""}, - {"Masthead.font", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Maximum heap size", "", "", "", ""}, - {"MBeanAttributeInfo", "", "", "", ""}, - {"MBeanInfo", "", "", "", ""}, - {"MBeanNotificationInfo", "", "", "", ""}, - {"MBeanOperationInfo", "", "", "", ""}, - {"MBeans", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.compositeNavigationSingle", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.tabularNavigationSingle", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""}, - {"Memory", "", "", "", ""}, - {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""}, - {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""}, - {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolChart.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""}, - {"Message", "", "", "", ""}, - {"Method successfully invoked", "", "", "", ""}, - {"Monitor locked", "", "", "", ""}, - {"Minimize All", "", "", "", ""}, - {"Minimize All.mnemonic", "", "", "", ""}, - {"Name", "", "", "", ""}, - {"Name and Build", "PhonyName", "PhonyBuild", "", ""}, - {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""}, - {"Name State", "PhonyName", "PhonyState", "", ""}, - {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""}, - {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"}, - {"New Connection...", "", "", "", ""}, - {"New Connection....mnemonic", "", "", "", ""}, - {"No deadlock detected", "", "", "", ""}, - {"Non-Heap", "", "", "", ""}, - {"Non-Heap Memory Usage", "", "", "", ""}, - {"Notification", "", "", "", ""}, - {"Notification buffer", "", "", "", ""}, - {"Notifications", "", "", "", ""}, - {"NotifTypes", "", "", "", ""}, - {"Number of Loaded Classes", "", "", "", ""}, - {"Number of processors", "", "", "", ""}, - {"Number of Threads", "", "", "", ""}, - {"ObjectName", "", "", "", ""}, - {"Operating System", "", "", "", ""}, - {"Operation", "", "", "", ""}, - {"Operation invocation", "", "", "", ""}, - {"Operation return value", "", "", "", ""}, - {"Operations", "", "", "", ""}, - {"Overview", "", "", "", ""}, - {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""}, - {"Parameter", "", "", "", ""}, - {"Password: ", "", "", "", ""}, - {"Password: .mnemonic", "", "", "", ""}, - {"Password.accessibleName", "", "", "", ""}, - {"Peak", "", "", "", ""}, - {"Perform GC", "", "", "", ""}, - {"Perform GC.mnemonic", "", "", "", ""}, - {"Perform GC.toolTip", "", "", "", ""}, - {"Plotter.accessibleName", "", "", "", ""}, - {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""}, - {"Plotter.accessibleName.noData", "", "", "", ""}, - {"Plotter.saveAsMenuItem", "", "", "", ""}, - {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""}, - {"Plotter.timeRangeMenu", "", "", "", ""}, - {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""}, - {"plot", "", "", "", ""}, - {"Problem adding listener", "", "", "", ""}, - {"Problem displaying MBean", "", "", "", ""}, - {"Problem invoking", "", "", "", ""}, - {"Problem removing listener", "", "", "", ""}, - {"Problem setting attribute", "", "", "", ""}, - {"Process CPU time", "", "", "", ""}, - {"Readable", "", "", "", ""}, - {"Reconnect", "", "", "", ""}, - {"Remote Process:", "", "", "", ""}, - {"Remote Process:.mnemonic", "", "", "", ""}, - {"Remote Process.textField.accessibleName", "", "", "", ""}, - {"remoteTF.usage", "", "", "", ""}, - {"Restore All", "", "", "", ""}, - {"Restore All.mnemonic", "", "", "", ""}, - {"ReturnType", "", "", "", ""}, - {"SeqNum", "", "", "", ""}, - {"Size Bytes", 512, "", "", ""}, - {"Size Gb", 512, "", "", ""}, - {"Size Kb", 512, "", "", ""}, - {"Size Mb", 512, "", "", ""}, - {"Source", "", "", "", ""}, - {"Stack trace", "", "", "", ""}, - {"SummaryTab.headerDateTimeFormat", "", "", "", ""}, - {"SummaryTab.pendingFinalization.label", "", "", "", ""}, - {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""}, - {"SummaryTab.tabName", "", "", "", ""}, - {"SummaryTab.vmVersion", "VMName", "VMVersion", "", ""}, - {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""}, - {"ThreadTab.threadInfo.accessibleName", "", "", "", ""}, - {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""}, - {"Threads", "", "", "", ""}, - {"Threshold", "", "", "", ""}, - {"Tile", "", "", "", ""}, - {"Tile.mnemonic", "", "", "", ""}, - {"Time", "", "", "", ""}, - {"Time Range:", "", "", "", ""}, - {"Time Range:.mnemonic", "", "", "", ""}, - {"TimeStamp", "", "", "", ""}, - {"Total classes loaded", "", "", "", ""}, - {"Total classes unloaded", "", "", "", ""}, - {"Total compile time", "", "", "", ""}, - {"Total Loaded", "", "", "", ""}, - {"Total physical memory", "", "", "", ""}, - {"Total swap space", "", "", "", ""}, - {"Total threads started", "", "", "", ""}, - {"Type", "", "", "", ""}, - {"Unavailable", "", "", "", ""}, - {"UNKNOWN", "", "", "", ""}, - {"Unregister", "", "", "", ""}, - {"Uptime", "", "", "", ""}, - {"Usage Threshold", "", "", "", ""}, - {"Used", "", "", "", ""}, - {"Username: ", "", "", "", ""}, - {"Username: .mnemonic", "", "", "", ""}, - {"Username.accessibleName", "", "", "", ""}, - {"UserData", "", "", "", ""}, - {"Value", "", "", "", ""}, - {"Vendor", "", "", "", ""}, - {"Verbose Output", "", "", "", ""}, - {"Verbose Output.toolTip", "", "", "", ""}, - {"visualize", "", "", "", ""}, - {"VM", "", "", "", ""}, - {"VMInternalFrame.accessibleDescription", "", "", "", ""}, - {"VM arguments", "", "", "", ""}, - {"Virtual Machine", "", "", "", ""}, - {"Window", "", "", "", ""}, - {"Window.mnemonic", "", "", "", ""}, - {"Writable", "", "", "", ""}, - {"zz usage text", "PhonyName", "", "", ""}, - }; - //boolean verbose = false; - boolean verbose = true; - - long badLookups = 0; - System.out.println("Start..."); - for (int ii = 0; ii < testData.length; ii++) { - String key = (String)testData[ii][0]; - - if (key.endsWith(".mnemonic")) { - String baseKey = key.substring(0, key.length() - ".mnemonic".length()); - int mnemonic = Resources.getMnemonicInt(baseKey); - if (mnemonic == 0) { - badLookups++; - System.out.println("****lookup failed for key = " + key); + public static void main(String... args) { + List errors = new ArrayList<>(); + // Ensure that all Message fields have a corresponding key/value + // in the resource bundle and that mnemonics can be looked + // up where applicable. + ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE); + for (Field field : Messages.class.getFields()) { + if (isResourceKeyField(field)) { + String resourceKey = field.getName(); + String message = readField(field); + if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) { + errors.add("Can't find message (and perhaps mnemonic) for " + + Messages.class.getSimpleName() + "." + + resourceKey + " in resource bundle."); } else { - if (verbose) { - System.out.println(" mnemonic: " + KeyEvent.getKeyText(mnemonic)); + String resourceMessage = rb.getString(resourceKey); + if (hasMnemonicIdentifier(resourceMessage)) { + int mi = Resources.getMnemonicInt(message); + if (mi == 0) { + errors.add("Could not look up mnemonic for message '" + + message + "'."); + } } } - continue; - } - - String ss = Resources.getText(key, - testData[ii][1], - testData[ii][2], - testData[ii][3], - testData[ii][4]); - if (ss.startsWith("missing resource key")) { - badLookups++; - System.out.println("****lookup failed for key = " + key); - } else { - if (verbose) { - System.out.println(" " + ss); - } } } - if (badLookups > 0) { - throw new Error ("Resource lookup failed " + badLookups + - " time(s); Test failed"); + + // Ensure that there is Message class field for every resource key. + for (String key : Collections.list(rb.getKeys())) { + try { + Messages.class.getField(key); + } catch (NoSuchFieldException nfe) { + errors.add("Can't find static field (" + + Messages.class.getSimpleName() + "." + key + + ") matching '" + key + + "' in resource bundle. Unused message?"); + } + } + + if (errors.size() > 0) { + throwError(errors); + } + } + + private static String readField(Field field) { + try { + return (String) field.get(null); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new Error("Could not access field " + field.getName() + + " when trying to read resource message."); } - System.out.println("...Finished."); + } + + private static boolean isResourceKeyField(Field field) { + int modifiers = field.getModifiers(); + return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); + } + + private static boolean hasMnemonicIdentifier(String s) { + for (int i = 0; i < s.length() - 1; i++) { + if (s.charAt(i) == '&') { + if (s.charAt(i + 1) != '&') { + return true; + } else { + i++; + } + } + } + return false; + } + + private static void throwError(List errors) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Found "); + buffer.append(errors.size()); + buffer.append(" error(s) when checking one-to-one mapping "); + buffer.append("between Message and resource bundle keys in "); + buffer.append(RESOURCE_BUNDLE); + buffer.append(" with "); + buffer.append(Locale.getDefault()); + buffer.append(" locale."); + buffer.append(NEW_LINE); + int errorIndex = 1; + for (String error : errors) { + buffer.append("Error "); + buffer.append(errorIndex); + buffer.append(": "); + buffer.append(error); + buffer.append(NEW_LINE); + errorIndex++; + } + throw new Error(buffer.toString()); } } diff -r 528fc8f4281b -r be6ca7197e0e test/sun/tools/jconsole/ResourceCheckTest.sh --- a/test/sun/tools/jconsole/ResourceCheckTest.sh Tue Aug 27 16:06:01 2013 -0300 +++ b/test/sun/tools/jconsole/ResourceCheckTest.sh Fri Sep 13 10:15:36 2013 -0300 @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin) PATHSEP=":" ;; diff -r 528fc8f4281b -r be6ca7197e0e test/sun/util/locale/provider/Bug8024141.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/util/locale/provider/Bug8024141.java Fri Sep 13 10:15:36 2013 -0300 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024141 + * @summary Test for cache support of sun.util.locale.provider.LocaleResources.getTimeZoneNames + */ + +import java.time.ZoneId; +import static java.util.Locale.ENGLISH; +import static java.time.format.TextStyle.FULL; +import static java.time.format.TextStyle.SHORT; + +public class Bug8024141 { + // This test assumes that the two time zones are in GMT. If + // they become different zones, need to pick up another zones. + private static final String[] ZONES = { + "Africa/Abidjan", + "Africa/Bamako" + }; + + public static void main(String[] args) { + ZoneId gmt = ZoneId.of("GMT"); + String gmtName = gmt.getDisplayName(FULL, ENGLISH); + String gmtAbbr = gmt.getDisplayName(SHORT, ENGLISH); + + for (String zone : ZONES) { + ZoneId id = ZoneId.of(zone); + String name = id.getDisplayName(FULL, ENGLISH); + String abbr = id.getDisplayName(SHORT, ENGLISH); + + if (!name.equals(gmtName) || !abbr.equals(gmtAbbr)) { + throw new RuntimeException("inconsistent name/abbr for " + zone + ":\n" + + "name=" + name + ", abbr=" + abbr); + } + } + } +}