# HG changeset patch # User kamg # Date 1227298214 18000 # Node ID bb12ee0dbc91208f7e7c84312327fe5d8bb8fd5f # Parent 776009a044964e95a4c92cd7bab71309cb2ee344# Parent c7dd0b46dfda98b3ac447e5350e641d2c7cfa9cd Merge diff -r 776009a04496 -r bb12ee0dbc91 .hgtags --- a/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ d718a441936196b93d8bc9f084933af9a4c2a350 jdk7-b36 c2036bf76829c03b99108fffab52e20910a9be4f jdk7-b37 a2879b2837f5a4c87e9542efe69ef138194af8ff jdk7-b38 +126f365cec6c3c2c72de934fa1c64b5f082b55b5 jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 .hgtags-top-repo --- a/.hgtags-top-repo Fri Nov 21 08:09:11 2008 -0800 +++ b/.hgtags-top-repo Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ 4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36 744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37 cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38 +ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 corba/.hgtags --- a/corba/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/corba/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ 0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36 59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37 08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38 +55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 hotspot/.hgtags --- a/hotspot/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36 9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37 d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38 +49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/hotspot_version --- a/hotspot/make/hotspot_version Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/hotspot_version Fri Nov 21 15:10:14 2008 -0500 @@ -35,7 +35,7 @@ HS_MAJOR_VER=14 HS_MINOR_VER=0 -HS_BUILD_NUMBER=06 +HS_BUILD_NUMBER=07 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/linux/makefiles/top.make --- a/hotspot/make/linux/makefiles/top.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/linux/makefiles/top.make Fri Nov 21 15:10:14 2008 -0500 @@ -85,9 +85,9 @@ AD_Dir = $(GENERATED)/adfiles ADLC = $(AD_Dir)/adlc -AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad +AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad AD_Src = $(GAMMADIR)/src/share/vm/adlc -AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp +AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp AD_Files = $(AD_Names:%=$(AD_Dir)/%) # AD_Files_If_Required/COMPILER1 = ad_stuff diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/amd64.make --- a/hotspot/make/solaris/makefiles/amd64.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/amd64.make Fri Nov 21 15:10:14 2008 -0500 @@ -26,7 +26,6 @@ CFLAGS += -DVM_LITTLE_ENDIAN # Not included in includeDB because it has no dependencies -# Obj_Files += solaris_amd64.o Obj_Files += solaris_x86_64.o # @@ -38,8 +37,6 @@ # _lwp_create_interpose must have a frame OPT_CFLAGS/os_solaris_x86_64.o = -xO1 -# force C++ interpreter to be full optimization -#OPT_CFLAGS/interpret.o = -fast -O4 # Temporary until SS10 C++ compiler is fixed OPT_CFLAGS/generateOptoStub.o = -xO2 @@ -51,8 +48,6 @@ # gcc # The serviceability agent relies on frame pointer (%rbp) to walk thread stack CFLAGS += -fno-omit-frame-pointer -# force C++ interpreter to be full optimization -#OPT_CFLAGS/interpret.o = -O3 else # error diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/debug.make --- a/hotspot/make/solaris/makefiles/debug.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/debug.make Fri Nov 21 15:10:14 2008 -0500 @@ -30,7 +30,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") -ifeq ($(COMPILER_REV),5.8) +ifeq ($(COMPILER_REV_NUMERIC),508) # SS11 SEGV when compiling with -g and -xarch=v8, using different backend DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0 diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/dtrace.make --- a/hotspot/make/solaris/makefiles/dtrace.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/dtrace.make Fri Nov 21 15:10:14 2008 -0500 @@ -87,17 +87,16 @@ XLIBJVM_DB = 64/$(LIBJVM_DB) XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE) -XARCH = $(subst sparcv9,v9,$(shell echo $(ISA))) $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) @echo Making $@ $(QUIETLY) mkdir -p 64/ ; \ - $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \ + $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \ $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo Making $@ $(QUIETLY) mkdir -p 64/ ; \ - $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \ + $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \ $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor endif # ifneq ("${ISA}","${BUILDARCH}") @@ -116,27 +115,25 @@ $(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \ ./lib$(GENOFFS).so -# $@.tmp is created first. It's to avoid empty $(JVMOFFS).h produced in error case. +CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \ + cmp -s $@ $@.tmp; \ + case $$? in \ + 0) rm -f $@.tmp;; \ + *) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \ + esac + +# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs. $(JVMOFFS).h: $(GENOFFS) - $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp ; \ - if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \ - then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \ - else rm -f $@.tmp; \ - fi + $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp + $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET) $(JVMOFFS)Index.h: $(GENOFFS) - $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp ; \ - if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \ - then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \ - else rm -f $@.tmp; \ - fi + $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp + $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET) $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h - $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp ; \ - if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \ - then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \ - else rm -f $@.tmp; \ - fi + $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp + $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET) $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp $(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/fastdebug.make --- a/hotspot/make/solaris/makefiles/fastdebug.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/fastdebug.make Fri Nov 21 15:10:14 2008 -0500 @@ -37,7 +37,7 @@ OPT_CFLAGS/SLOWER = -xO2 # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876) -ifeq ($(COMPILER_REV), 5.9) +ifeq ($(COMPILER_REV_NUMERIC), 509) # To avoid jvm98 crash OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER) # Not clear this workaround could be skipped in some cases. @@ -46,47 +46,41 @@ OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER) endif -ifeq ($(COMPILER_REV), 5.5) +ifeq ($(COMPILER_REV_NUMERIC), 505) # CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6) OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER) -endif # COMPILER_REV == 5.5 +endif # COMPILER_REV_NUMERIC == 505 -ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \<= 504), 1) # Compilation of *_.cpp can take an hour or more at O3. Use O2 # See comments at top of sparc.make. -OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER) -OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER) -endif # COMPILER_REV <= 5.4 +OPT_CFLAGS/ad_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER) +OPT_CFLAGS/dfa_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER) +endif # COMPILER_REV_NUMERIC <= 504 -ifeq (${COMPILER_REV}, 5.0) -# Avoid a compiler bug caused by using -xO -g -# Since the bug also occurs with -xO0, use an innocuous value (must not be null) -OPT_CFLAGS/c1_LIROptimizer_i486.o = -c -endif - -ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1) -# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_i486.cpp. -# CC build time is also too long for ad_i486_{gen,misc}.o -OPT_CFLAGS/ad_i486.o = -c -OPT_CFLAGS/ad_i486_gen.o = -c -OPT_CFLAGS/ad_i486_misc.o = -c -ifeq ($(Platform_arch), i486) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1) +# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_x86_{32,64}.cpp. +# CC build time is also too long for ad_$(Platform_arch_model)_{gen,misc}.o +OPT_CFLAGS/ad_$(Platform_arch_model).o = -c +OPT_CFLAGS/ad_$(Platform_arch_model)_gen.o = -c +OPT_CFLAGS/ad_$(Platform_arch_model)_misc.o = -c +ifeq ($(Platform_arch), x86) # Same problem for the wrapper roosts: jni.o jvm.o OPT_CFLAGS/jni.o = -c OPT_CFLAGS/jvm.o = -c # Same problem in parse2.o (probably the Big Switch over bytecodes) OPT_CFLAGS/parse2.o = -c -endif # Platform_arch == i486 +endif # Platform_arch == x86 endif # Frame size > 100k if we allow inlining via -g0! DEBUG_CFLAGS/bytecodeInterpreter.o = -g DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g -ifeq ($(Platform_arch), i486) +ifeq ($(Platform_arch), x86) # ube explodes on x86 OPT_CFLAGS/bytecodeInterpreter.o = -xO1 OPT_CFLAGS/bytecodeInterpreterWithChecks.o = -xO1 -endif # Platform_arch == i486 +endif # Platform_arch == x86 endif # Platform_compiler == sparcWorks diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/i486.make --- a/hotspot/make/solaris/makefiles/i486.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/i486.make Fri Nov 21 15:10:14 2008 -0500 @@ -35,17 +35,13 @@ ifeq ("${Platform_compiler}", "sparcWorks") # _lwp_create_interpose must have a frame -OPT_CFLAGS/os_solaris_i486.o = -xO1 -# force C++ interpreter to be full optimization -OPT_CFLAGS/interpret.o = -fast -O4 +OPT_CFLAGS/os_solaris_x86.o = -xO1 else ifeq ("${Platform_compiler}", "gcc") # gcc # _lwp_create_interpose must have a frame -OPT_CFLAGS/os_solaris_i486.o = -fno-omit-frame-pointer -# force C++ interpreter to be full optimization -OPT_CFLAGS/interpret.o = -O3 +OPT_CFLAGS/os_solaris_x86.o = -fno-omit-frame-pointer # else # error @@ -57,7 +53,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") # ILD is gone as of SS11 (5.8), not supported in SS10 (5.7) -ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1) # # Bug in ild causes it to fail randomly. Until we get a fix we can't # use ild. diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/jvmg.make --- a/hotspot/make/solaris/makefiles/jvmg.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/jvmg.make Fri Nov 21 15:10:14 2008 -0500 @@ -30,7 +30,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") -ifeq ($(COMPILER_REV),5.8) +ifeq ($(COMPILER_REV_NUMERIC),508) # SS11 SEGV when compiling with -g and -xarch=v8, using different backend DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0 diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/optimized.make --- a/hotspot/make/solaris/makefiles/optimized.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/optimized.make Fri Nov 21 15:10:14 2008 -0500 @@ -33,7 +33,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876) -ifeq ($(COMPILER_REV),5.9) +ifeq ($(COMPILER_REV_NUMERIC),509) # Not clear this workaround could be skipped in some cases. OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g @@ -41,9 +41,9 @@ endif # Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12) -ifeq ($(COMPILER_REV),5.8)) +ifeq ($(COMPILER_REV_NUMERIC),508)) OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2) -endif # COMPILER_REV == 5.8 +endif # COMPILER_REV_NUMERIC == 508 endif # Platform_compiler == sparcWorks diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/product.make --- a/hotspot/make/solaris/makefiles/product.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/product.make Fri Nov 21 15:10:14 2008 -0500 @@ -41,7 +41,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876) -ifeq ($(COMPILER_REV),5.9) +ifeq ($(COMPILER_REV_NUMERIC),509) # Not clear this workaround could be skipped in some cases. OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g @@ -49,9 +49,9 @@ endif # Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12) -ifeq ($(COMPILER_REV),5.8) +ifeq ($(COMPILER_REV_NUMERIC),508) OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2) -endif # COMPILER_REV == 5.8 +endif # COMPILER_REV_NUMERIC == 508 endif # Platform_compiler == sparcWorks diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/sparc.make --- a/hotspot/make/solaris/makefiles/sparc.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/sparc.make Fri Nov 21 15:10:14 2008 -0500 @@ -26,7 +26,7 @@ ASFLAGS += $(AS_ARCHFLAG) ifeq ("${Platform_compiler}", "sparcWorks") -ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1) # For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER) @@ -39,7 +39,7 @@ OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2) # CC brings an US-II to its knees compiling the vmStructs asserts under -xO4 OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2) -endif +endif # COMPILER_REV_NUMERIC < 505 else # Options for gcc OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER) diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/sparcWorks.make --- a/hotspot/make/solaris/makefiles/sparcWorks.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/sparcWorks.make Fri Nov 21 15:10:14 2008 -0500 @@ -41,9 +41,9 @@ # Get the last thing on the line that looks like x.x+ (x is a digit). COMPILER_REV := \ -$(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/') +$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p') C_COMPILER_REV := \ -$(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/') +$(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p') # Pick which compiler is validated ifeq ($(JDK_MINOR_VERSION),6) @@ -60,17 +60,19 @@ ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV} ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV}) dummy_target_to_enforce_compiler_rev:=\ -$(info WARNING: You are using CC version ${COMPILER_REV} \ -and should be using version ${ENFORCE_COMPILER_REV}) +$(shell echo >&2 WARNING: You are using CC version ${COMPILER_REV} \ +and should be using version ${ENFORCE_COMPILER_REV}. Set ENFORCE_COMPILER_REV=${COMPILER_REV} to avoid this warning.) endif ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV} ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV}) dummy_target_to_enforce_c_compiler_rev:=\ -$(info WARNING: You are using cc version ${C_COMPILER_REV} \ -and should be using version ${ENFORCE_C_COMPILER_REV}) +$(shell echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} \ +and should be using version ${ENFORCE_C_COMPILER_REV}. Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this warning.) endif +COMPILER_REV_NUMERIC := $(shell echo $(COMPILER_REV) | awk -F. '{ print $$1 * 100 + $$2 }') + # Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04 # and newer; objects with a dependency on this symbol will not run on older # Solaris 8. @@ -120,7 +122,7 @@ ARCHFLAG_NEW/amd64 = -m64 # Select the ARCHFLAGs and other SS12 (5.9) options -ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1) ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc) ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9) ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486) @@ -150,7 +152,7 @@ # Begin current (>=5.6) Forte compiler options # ################################################# -ifeq ($(shell expr $(COMPILER_REV) \>= 5.6), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 506), 1) ifeq ("${Platform_arch}", "sparc") @@ -167,7 +169,7 @@ # Begin current (>=5.5) Forte compiler options # ################################################# -ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1) CFLAGS += $(ARCHFLAG) AOUT_FLAGS += $(ARCHFLAG) @@ -255,7 +257,7 @@ LFLAGS += -mt -endif # COMPILER_REV >= 5.5 +endif # COMPILER_REV_NUMERIC >= 505 ###################################### # End 5.5 Forte compiler options # @@ -265,7 +267,7 @@ # Begin 5.2 Forte compiler options # ###################################### -ifeq ($(COMPILER_REV), 5.2) +ifeq ($(COMPILER_REV_NUMERIC), 502) CFLAGS += $(ARCHFLAG) AOUT_FLAGS += $(ARCHFLAG) @@ -324,7 +326,7 @@ LFLAGS += -library=Crun LIBS += -library=Crun -lCrun -endif # COMPILER_REV == 5.2 +endif # COMPILER_REV_NUMERIC == 502 ################################## # End 5.2 Forte compiler options # @@ -333,7 +335,7 @@ ################################## # Begin old 5.1 compiler options # ################################## -ifeq ($(COMPILER_REV), 5.1) +ifeq ($(COMPILER_REV_NUMERIC), 501) _JUNK_ := $(shell echo >&2 \ "*** ERROR: sparkWorks.make incomplete for 5.1 compiler") @@ -347,7 +349,7 @@ # Begin old 5.0 compiler options # ################################## -ifeq (${COMPILER_REV}, 5.0) +ifeq (${COMPILER_REV_NUMERIC}, 500) # Had to hoist this higher apparently because of other changes. Must # come before -xarch specification. @@ -379,7 +381,7 @@ ifeq ("${Platform_arch_model}", "x86_32") OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS) -ifeq ("${COMPILER_REV}", "5.0") +ifeq ("${COMPILER_REV_NUMERIC}", "500") # SC5.0 tools on x86 are flakey at -xO4 OPT_CFLAGS+=-xO3 else @@ -405,13 +407,13 @@ PICFLAG/BETTER = $(PICFLAG/DEFAULT) PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@)) -endif # COMPILER_REV = 5.0 +endif # COMPILER_REV_NUMERIC = 500 ################################ # End old 5.0 compiler options # ################################ -ifeq ("${COMPILER_REV}", "4.2") +ifeq ("${COMPILER_REV_NUMERIC}", "402") # 4.2 COMPILERS SHOULD NO LONGER BE USED _JUNK_ := $(shell echo >&2 \ "*** ERROR: SC4.2 compilers are not supported by this code base!") @@ -443,7 +445,7 @@ LINK_MODE/optimized = -Bsymbolic -znodefs # Have thread local errnos -ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1) CFLAGS += -mt else CFLAGS += -D_REENTRANT @@ -460,7 +462,7 @@ # The -g0 setting allows the C++ frontend to inline, which is a big win. # Special global options for SS12 -ifeq ($(COMPILER_REV),5.9) +ifeq ($(COMPILER_REV_NUMERIC),509) # There appears to be multiple issues with the new Dwarf2 debug format, so # we tell the compiler to use the older 'stabs' debug format all the time. # Note that this needs to be used in optimized compiles too to be 100%. @@ -479,8 +481,8 @@ #DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic #FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic -ifeq (${COMPILER_REV}, 5.2) -COMPILER_DATE := $(shell $(CPP) -V 2>&1 | awk '{ print $$NF; }') +ifeq (${COMPILER_REV_NUMERIC}, 502) +COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }') ifeq (${COMPILER_DATE}, 2001/01/31) # disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy # use an innocuous value because it will get -g if it's empty @@ -493,7 +495,7 @@ CFLAGS += $(CFLAGS_BROWSE) # ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7) -ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1) # use ild when debugging (but when optimizing we want reproducible results) ILDFLAG = $(ILDFLAG/$(VERSION)) ILDFLAG/debug = -xildon diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/sparcv9.make --- a/hotspot/make/solaris/makefiles/sparcv9.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/sparcv9.make Fri Nov 21 15:10:14 2008 -0500 @@ -26,7 +26,7 @@ ASFLAGS += $(AS_ARCHFLAG) ifeq ("${Platform_compiler}", "sparcWorks") -ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1) # When optimized fully, stubGenerator_sparc.cpp # has bogus code for the routine # StubGenerator::generate_flush_callers_register_windows() diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/top.make --- a/hotspot/make/solaris/makefiles/top.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/top.make Fri Nov 21 15:10:14 2008 -0500 @@ -83,9 +83,9 @@ AD_Dir = $(GENERATED)/adfiles ADLC = $(AD_Dir)/adlc -AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad +AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad AD_Src = $(GAMMADIR)/src/share/vm/adlc -AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp +AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp AD_Files = $(AD_Names:%=$(AD_Dir)/%) # AD_Files_If_Required/COMPILER1 = ad_stuff diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/solaris/makefiles/vm.make --- a/hotspot/make/solaris/makefiles/vm.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/solaris/makefiles/vm.make Fri Nov 21 15:10:14 2008 -0500 @@ -101,7 +101,7 @@ ifeq ("${Platform_compiler}", "sparcWorks") # The whole megilla: -ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1) +ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1) # Old Comment: List the libraries in the order the compiler was designed for # Not sure what the 'designed for' comment is referring too above. # The order may not be too significant anymore, but I have placed this diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/adlc.make --- a/hotspot/make/windows/makefiles/adlc.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/adlc.make Fri Nov 21 15:10:14 2008 -0500 @@ -102,6 +102,12 @@ adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \ forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj $(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $** +!if "$(MT)" != "" +# The previous link command created a .manifest file that we want to +# insert into the linked artifact so we do not need to track it +# separately. Use ";#2" for .dll and ";#1" for .exe: + $(MT) /manifest $@.manifest /outputresource:$@;#1 +!endif $(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current rm -f $(GENERATED_NAMES) diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/compile.make --- a/hotspot/make/windows/makefiles/compile.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/compile.make Fri Nov 21 15:10:14 2008 -0500 @@ -30,7 +30,7 @@ # /W3 Warning level 3 # /Zi Include debugging information # /WX Treat any warning error as a fatal error -# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*71.dll) +# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll) # /MTd Use static multi-threaded runtime debug versions # /O1 Optimize for size (/Os), skips /Oi # /O2 Optimize for speed (/Ot), adds /Oi to /O1 @@ -80,8 +80,10 @@ CPP=ARCH_ERROR !endif -# MSC_VER is a 4 digit number that tells us what compiler is being used, it is -# generated when the local.make file is created by the script gen_msc_ver.sh. +# MSC_VER is a 4 digit number that tells us what compiler is being used +# and is generated when the local.make file is created by build.make +# via the script get_msc_ver.sh +# # If MSC_VER is set, it overrides the above default setting. # But it should be set. # Possible values: @@ -89,13 +91,14 @@ # 1300 and 1310 is VS2003 or VC7 # 1399 is our fake number for the VS2005 compiler that really isn't 1400 # 1400 is for VS2005 +# 1500 is for VS2008 # Do not confuse this MSC_VER with the predefined macro _MSC_VER that the # compiler provides, when MSC_VER==1399, _MSC_VER will be 1400. # Normally they are the same, but a pre-release of the VS2005 compilers # in the Windows 64bit Platform SDK said it was 1400 when it was really # closer to VS2003 in terms of option spellings, so we use 1399 for that # 1400 version that really isn't 1400. -# See the file gen_msc_ver.sh for more info. +# See the file get_msc_ver.sh for more info. !if "x$(MSC_VER)" == "x" COMPILER_NAME=$(DEFAULT_COMPILER_NAME) !else @@ -115,6 +118,9 @@ !if "$(MSC_VER)" == "1400" COMPILER_NAME=VS2005 !endif +!if "$(MSC_VER)" == "1500" +COMPILER_NAME=VS2008 +!endif !endif # Add what version of the compiler we think this is to the compile line @@ -160,7 +166,25 @@ # externals at link time. Even with /GS-, you need bufferoverflowU.lib. # NOTE: Currently we decided to not use /GS- BUFFEROVERFLOWLIB = bufferoverflowU.lib -LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) +LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB) +# Manifest Tool - used in VS2005 and later to adjust manifests stored +# as resources inside build artifacts. +MT=mt.exe +!if "$(BUILDARCH)" == "i486" +# VS2005 on x86 restricts the use of certain libc functions without this +CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE +!endif +!endif + +!if "$(COMPILER_NAME)" == "VS2008" +PRODUCT_OPT_OPTION = /O2 /Oy- +FASTDEBUG_OPT_OPTION = /O2 /Oy- +DEBUG_OPT_OPTION = /Od +GX_OPTION = /EHsc +LINK_FLAGS = /manifest $(LINK_FLAGS) +# Manifest Tool - used in VS2005 and later to adjust manifests stored +# as resources inside build artifacts. +MT=mt.exe !if "$(BUILDARCH)" == "i486" # VS2005 on x86 restricts the use of certain libc functions without this CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/debug.make --- a/hotspot/make/windows/makefiles/debug.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/debug.make Fri Nov 21 15:10:14 2008 -0500 @@ -50,6 +50,12 @@ $(LINK) @<< $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << +!if "$(MT)" != "" +# The previous link command created a .manifest file that we want to +# insert into the linked artifact so we do not need to track it +# separately. Use ";#2" for .dll and ";#1" for .exe: + $(MT) /manifest $@.manifest /outputresource:$@;#2 +!endif !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/defs.make --- a/hotspot/make/windows/makefiles/defs.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/defs.make Fri Nov 21 15:10:14 2008 -0500 @@ -25,7 +25,7 @@ # The common definitions for hotspot windows builds. # Include the top level defs.make under make directory instead of this one. # This file is included into make/defs.make. -# On windows it is only used to construct parameters for +# On windows it is only used to construct parameters for # make/windows/build.make when make/Makefile is used to build VM. SLASH_JAVA ?= J: @@ -69,7 +69,7 @@ JDK_INCLUDE_SUBDIR=win32 -# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined +# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined # and added to MAKE_ARGS list in $(GAMMADIR)/make/defs.make. # next parameters are defined in $(GAMMADIR)/make/defs.make. @@ -125,7 +125,7 @@ endif ifeq ($(BUILD_WIN_SA), 1) - ifeq ($(ARCH),ia64) + ifeq ($(ARCH),ia64) BUILD_WIN_SA = 0 endif endif @@ -154,7 +154,7 @@ EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.dll EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map - EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar + EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar # Must pass this down to nmake. MAKE_ARGS += BUILD_WIN_SA=1 endif diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/fastdebug.make --- a/hotspot/make/windows/makefiles/fastdebug.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/fastdebug.make Fri Nov 21 15:10:14 2008 -0500 @@ -50,6 +50,13 @@ $(LINK) @<< $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << +!if "$(MT)" != "" +# The previous link command created a .manifest file that we want to +# insert into the linked artifact so we do not need to track it +# separately. Use ";#2" for .dll and ";#1" for .exe: + $(MT) /manifest $@.manifest /outputresource:$@;#2 +!endif + !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/product.make --- a/hotspot/make/windows/makefiles/product.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/product.make Fri Nov 21 15:10:14 2008 -0500 @@ -61,6 +61,12 @@ $(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << !endif +!if "$(MT)" != "" +# The previous link command created a .manifest file that we want to +# insert into the linked artifact so we do not need to track it +# separately. Use ";#2" for .dll and ";#1" for .exe: + $(MT) /manifest $@.manifest /outputresource:$@;#2 +!endif !include $(WorkSpace)/make/windows/makefiles/shared.make !include $(WorkSpace)/make/windows/makefiles/sa.make diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/makefiles/sa.make --- a/hotspot/make/windows/makefiles/sa.make Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/makefiles/sa.make Fri Nov 21 15:10:14 2008 -0500 @@ -92,13 +92,18 @@ !else SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c !endif - +!if "$(MT)" != "" + SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS) +!endif SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE) # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh +# In VS2005 or VS2008 the link command creates a .manifest file that we want +# to insert into the linked artifact so we do not need to track it separately. +# Use ";#2" for .dll and ";#1" for .exe in the MT command below: $(SAWINDBG): $(SASRCFILE) set INCLUDE=$(SA_INCLUDE)$(INCLUDE) $(CPP) @<< @@ -109,6 +114,9 @@ << set LIB=$(SA_LIB)$(LIB) $(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS) +!if "$(MT)" != "" + $(MT) /manifest $(@F).manifest /outputresource:$(@F);#2 +!endif -@rm -f sawindbg.obj cleanall : diff -r 776009a04496 -r bb12ee0dbc91 hotspot/make/windows/projectfiles/common/Makefile --- a/hotspot/make/windows/projectfiles/common/Makefile Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/make/windows/projectfiles/common/Makefile Fri Nov 21 15:10:14 2008 -0500 @@ -56,7 +56,8 @@ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \ - $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep + $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep \ + $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_g1 IncludeDBs_kernel =$(IncludeDBs_base) \ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/cpu/x86/vm/register_definitions_x86.cpp --- a/hotspot/src/cpu/x86/vm/register_definitions_x86.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/cpu/x86/vm/register_definitions_x86.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -22,9 +22,6 @@ * */ -// make sure the defines don't screw up the declarations later on in this file -#define DONT_USE_REGISTER_DEFINES - #include "incls/_precompiled.incl" #include "incls/_register_definitions_x86.cpp.incl" diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -3756,7 +3756,6 @@ int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim); iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio); iaInfo->ia_uprilim = IA_NOCHANGE; - iaInfo->ia_nice = IA_NOCHANGE; iaInfo->ia_mode = IA_NOCHANGE; if (ThreadPriorityVerbose) { tty->print_cr ("IA: [%d...%d] %d->%d\n", diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/adlc/archDesc.cpp --- a/hotspot/src/share/vm/adlc/archDesc.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/adlc/archDesc.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -212,9 +212,9 @@ // Initialize I/O Files _ADL_file._name = NULL; _ADL_file._fp = NULL; // Machine dependent output files - _DFA_file._name = "dfa_i486.cpp"; _DFA_file._fp = NULL; - _HPP_file._name = "ad_i486.hpp"; _HPP_file._fp = NULL; - _CPP_file._name = "ad_i486.cpp"; _CPP_file._fp = NULL; + _DFA_file._name = NULL; _DFA_file._fp = NULL; + _HPP_file._name = NULL; _HPP_file._fp = NULL; + _CPP_file._name = NULL; _CPP_file._fp = NULL; _bug_file._name = "bugs.out"; _bug_file._fp = NULL; // Initialize Register & Pipeline Form Pointers diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/c1/c1_IR.cpp --- a/hotspot/src/share/vm/c1/c1_IR.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/c1/c1_IR.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -574,12 +574,23 @@ TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch")); assert(is_visited(cur), "block must be visisted when block is active"); assert(parent != NULL, "must have parent"); - assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)"); cur->set(BlockBegin::linear_scan_loop_header_flag); cur->set(BlockBegin::backward_branch_target_flag); parent->set(BlockBegin::linear_scan_loop_end_flag); + + // When a loop header is also the start of an exception handler, then the backward branch is + // an exception edge. Because such edges are usually critical edges which cannot be split, the + // loop must be excluded here from processing. + if (cur->is_set(BlockBegin::exception_entry_flag)) { + // Make sure that dominators are correct in this weird situation + _iterative_dominators = true; + return; + } + assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur, + "loop end blocks must have one successor (critical edges are split)"); + _loop_end_blocks.append(parent); return; } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -484,11 +484,16 @@ } else if (tag.is_double()) { return ciConstant((jdouble)cpool->double_at(index)); } else if (tag.is_string() || tag.is_unresolved_string()) { - oop string = cpool->string_at(index, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - record_out_of_memory_failure(); - return ciConstant(); + oop string = NULL; + if (cpool->is_pseudo_string_at(index)) { + string = cpool->pseudo_string_at(index); + } else { + string = cpool->string_at(index, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + record_out_of_memory_failure(); + return ciConstant(); + } } ciObject* constant = get_object(string); assert (constant->is_instance(), "must be an instance, or not? "); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -168,11 +168,23 @@ // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward. cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags cfs->skip_u1_fast(utf8_length); + // Before storing the symbol, make sure it's legal if (_need_verify) { verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK); } + if (AnonymousClasses && has_cp_patch_at(index)) { + Handle patch = clear_cp_patch_at(index); + guarantee_property(java_lang_String::is_instance(patch()), + "Illegal utf8 patch at %d in class file %s", + index, CHECK); + char* str = java_lang_String::as_utf8_string(patch()); + // (could use java_lang_String::as_symbol instead, but might as well batch them) + utf8_buffer = (u1*) str; + utf8_length = (int) strlen(str); + } + unsigned int hash; symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash); if (result == NULL) { @@ -245,7 +257,7 @@ int klass_ref_index = cp->klass_ref_index_at(index); int name_and_type_ref_index = cp->name_and_type_ref_index_at(index); check_property(valid_cp_range(klass_ref_index, length) && - cp->tag_at(klass_ref_index).is_klass_reference(), + is_klass_reference(cp, klass_ref_index), "Invalid constant pool index %u in class file %s", klass_ref_index, CHECK_(nullHandle)); @@ -326,16 +338,46 @@ } // end of switch } // end of for + if (_cp_patches != NULL) { + // need to treat this_class specially... + assert(AnonymousClasses, ""); + int this_class_index; + { + cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len + u1* mark = cfs->current(); + u2 flags = cfs->get_u2_fast(); + this_class_index = cfs->get_u2_fast(); + cfs->set_current(mark); // revert to mark + } + + for (index = 1; index < length; index++) { // Index 0 is unused + if (has_cp_patch_at(index)) { + guarantee_property(index != this_class_index, + "Illegal constant pool patch to self at %d in class file %s", + index, CHECK_(nullHandle)); + patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle)); + } + } + // Ensure that all the patches have been used. + for (index = 0; index < _cp_patches->length(); index++) { + guarantee_property(!has_cp_patch_at(index), + "Unused constant pool patch at %d in class file %s", + index, CHECK_(nullHandle)); + } + } + if (!_need_verify) { return cp; } // second verification pass - checks the strings are of the right format. + // but not yet to the other entries for (index = 1; index < length; index++) { jbyte tag = cp->tag_at(index).value(); switch (tag) { case JVM_CONSTANT_UnresolvedClass: { symbolHandle class_name(THREAD, cp->unresolved_klass_at(index)); + // check the name, even if _cp_patches will overwrite it verify_legal_class_name(class_name, CHECK_(nullHandle)); break; } @@ -378,6 +420,73 @@ } +void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) { + assert(AnonymousClasses, ""); + BasicType patch_type = T_VOID; + switch (cp->tag_at(index).value()) { + + case JVM_CONSTANT_UnresolvedClass : + // Patching a class means pre-resolving it. + // The name in the constant pool is ignored. + if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance + guarantee_property(!java_lang_Class::is_primitive(patch()), + "Illegal class patch at %d in class file %s", + index, CHECK); + cp->klass_at_put(index, java_lang_Class::as_klassOop(patch())); + } else { + guarantee_property(java_lang_String::is_instance(patch()), + "Illegal class patch at %d in class file %s", + index, CHECK); + symbolHandle name = java_lang_String::as_symbol(patch(), CHECK); + cp->unresolved_klass_at_put(index, name()); + } + break; + + case JVM_CONSTANT_UnresolvedString : + // Patching a string means pre-resolving it. + // The spelling in the constant pool is ignored. + // The constant reference may be any object whatever. + // If it is not a real interned string, the constant is referred + // to as a "pseudo-string", and must be presented to the CP + // explicitly, because it may require scavenging. + cp->pseudo_string_at_put(index, patch()); + break; + + case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim; + case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim; + case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim; + case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim; + patch_prim: + { + jvalue value; + BasicType value_type = java_lang_boxing_object::get_value(patch(), &value); + guarantee_property(value_type == patch_type, + "Illegal primitive patch at %d in class file %s", + index, CHECK); + switch (value_type) { + case T_INT: cp->int_at_put(index, value.i); break; + case T_FLOAT: cp->float_at_put(index, value.f); break; + case T_LONG: cp->long_at_put(index, value.j); break; + case T_DOUBLE: cp->double_at_put(index, value.d); break; + default: assert(false, ""); + } + } + break; + + default: + // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc. + guarantee_property(!has_cp_patch_at(index), + "Illegal unexpected patch at %d in class file %s", + index, CHECK); + return; + } + + // On fall-through, mark the patch as used. + clear_cp_patch_at(index); +} + + + class NameSigHash: public ResourceObj { public: symbolOop _name; // name @@ -448,25 +557,32 @@ int index; for (index = 0; index < length; index++) { u2 interface_index = cfs->get_u2(CHECK_(nullHandle)); + KlassHandle interf; check_property( valid_cp_range(interface_index, cp->length()) && - cp->tag_at(interface_index).is_unresolved_klass(), + is_klass_reference(cp, interface_index), "Interface name has bad constant pool index %u in class file %s", interface_index, CHECK_(nullHandle)); - symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index)); - - // Don't need to check legal name because it's checked when parsing constant pool. - // But need to make sure it's not an array type. - guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, - "Bad interface name in class file %s", CHECK_(nullHandle)); - - vmtimer->suspend(); // do not count recursive loading twice - // Call resolve_super so classcircularity is checked - klassOop k = SystemDictionary::resolve_super_or_fail(class_name, - unresolved_klass, class_loader, protection_domain, - false, CHECK_(nullHandle)); - KlassHandle interf (THREAD, k); - vmtimer->resume(); + if (cp->tag_at(interface_index).is_klass()) { + interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index)); + } else { + symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index)); + + // Don't need to check legal name because it's checked when parsing constant pool. + // But need to make sure it's not an array type. + guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY, + "Bad interface name in class file %s", CHECK_(nullHandle)); + + vmtimer->suspend(); // do not count recursive loading twice + // Call resolve_super so classcircularity is checked + klassOop k = SystemDictionary::resolve_super_or_fail(class_name, + unresolved_klass, class_loader, protection_domain, + false, CHECK_(nullHandle)); + interf = KlassHandle(THREAD, k); + vmtimer->resume(); + + cp->klass_at_put(interface_index, interf()); // eagerly resolve + } if (!Klass::cast(interf())->is_interface()) { THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle); @@ -877,8 +993,7 @@ "Illegal exception table handler in class file %s", CHECK_(nullHandle)); if (catch_type_index != 0) { guarantee_property(valid_cp_range(catch_type_index, cp->length()) && - (cp->tag_at(catch_type_index).is_klass() || - cp->tag_at(catch_type_index).is_unresolved_klass()), + is_klass_reference(cp, catch_type_index), "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle)); } } @@ -1117,7 +1232,7 @@ } else if (tag == ITEM_Object) { u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK); guarantee_property(valid_cp_range(class_index, cp->length()) && - cp->tag_at(class_index).is_unresolved_klass(), + is_klass_reference(cp, class_index), "Bad class index %u in StackMap in class file %s", class_index, CHECK); } else if (tag == ITEM_Uninitialized) { @@ -1183,7 +1298,7 @@ checked_exception = cfs->get_u2_fast(); check_property( valid_cp_range(checked_exception, cp->length()) && - cp->tag_at(checked_exception).is_klass_reference(), + is_klass_reference(cp, checked_exception), "Exception name has bad type at constant pool %u in class file %s", checked_exception, CHECK_NULL); } @@ -1918,7 +2033,7 @@ check_property( inner_class_info_index == 0 || (valid_cp_range(inner_class_info_index, cp_size) && - cp->tag_at(inner_class_info_index).is_klass_reference()), + is_klass_reference(cp, inner_class_info_index)), "inner_class_info_index %u has bad constant type in class file %s", inner_class_info_index, CHECK_0); // Outer class index @@ -1926,7 +2041,7 @@ check_property( outer_class_info_index == 0 || (valid_cp_range(outer_class_info_index, cp_size) && - cp->tag_at(outer_class_info_index).is_klass_reference()), + is_klass_reference(cp, outer_class_info_index)), "outer_class_info_index %u has bad constant type in class file %s", outer_class_info_index, CHECK_0); // Inner class name @@ -2088,7 +2203,7 @@ } // Validate the constant pool indices and types if (!cp->is_within_bounds(class_index) || - !cp->tag_at(class_index).is_klass_reference()) { + !is_klass_reference(cp, class_index)) { classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK); } if (method_index != 0 && @@ -2349,6 +2464,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, Handle class_loader, Handle protection_domain, + GrowableArray* cp_patches, symbolHandle& parsed_name, TRAPS) { // So that JVMTI can cache class file in the state before retransformable agents @@ -2380,6 +2496,7 @@ } } + _cp_patches = cp_patches; instanceKlassHandle nullHandle; @@ -2510,14 +2627,22 @@ CHECK_(nullHandle)); } else { check_property(valid_cp_range(super_class_index, cp_size) && - cp->tag_at(super_class_index).is_unresolved_klass(), + is_klass_reference(cp, super_class_index), "Invalid superclass index %u in class file %s", super_class_index, CHECK_(nullHandle)); // The class name should be legal because it is checked when parsing constant pool. // However, make sure it is not an array type. + bool is_array = false; + if (cp->tag_at(super_class_index).is_klass()) { + super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index)); + if (_need_verify) + is_array = super_klass->oop_is_array(); + } else if (_need_verify) { + is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY); + } if (_need_verify) { - guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY, + guarantee_property(!is_array, "Bad superclass name in class file %s", CHECK_(nullHandle)); } } @@ -2557,7 +2682,7 @@ objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop); // We check super class after class file is parsed and format is checked - if (super_class_index > 0) { + if (super_class_index > 0 && super_klass.is_null()) { symbolHandle sk (THREAD, cp->klass_name_at(super_class_index)); if (access_flags.is_interface()) { // Before attempting to resolve the superclass, check for class format @@ -2574,6 +2699,9 @@ CHECK_(nullHandle)); KlassHandle kh (THREAD, k); super_klass = instanceKlassHandle(THREAD, kh()); + cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve + } + if (super_klass.not_null()) { if (super_klass->is_interface()) { ResourceMark rm(THREAD); Exceptions::fthrow( @@ -3000,6 +3128,7 @@ this_klass->set_method_ordering(method_ordering()); this_klass->set_initial_method_idnum(methods->length()); this_klass->set_name(cp->klass_name_at(this_class_index)); + cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve this_klass->set_protection_domain(protection_domain()); this_klass->set_fields_annotations(fields_annotations()); this_klass->set_methods_annotations(methods_annotations()); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/classfile/classFileParser.hpp --- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -33,6 +33,7 @@ u2 _major_version; u2 _minor_version; symbolHandle _class_name; + GrowableArray* _cp_patches; // overrides for CP entries bool _has_finalizer; bool _has_empty_finalizer; @@ -203,6 +204,35 @@ char* skip_over_field_name(char* name, bool slash_ok, unsigned int length); char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS); + bool has_cp_patch_at(int index) { + assert(AnonymousClasses, ""); + assert(index >= 0, "oob"); + return (_cp_patches != NULL + && index < _cp_patches->length() + && _cp_patches->adr_at(index)->not_null()); + } + Handle cp_patch_at(int index) { + assert(has_cp_patch_at(index), "oob"); + return _cp_patches->at(index); + } + Handle clear_cp_patch_at(int index) { + Handle patch = cp_patch_at(index); + _cp_patches->at_put(index, Handle()); + assert(!has_cp_patch_at(index), ""); + return patch; + } + void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS); + + // Wrapper for constantTag.is_klass_[or_]reference. + // In older versions of the VM, klassOops cannot sneak into early phases of + // constant pool construction, but in later versions they can. + // %%% Let's phase out the old is_klass_reference. + bool is_klass_reference(constantPoolHandle cp, int index) { + return ((LinkWellKnownClasses || AnonymousClasses) + ? cp->tag_at(index).is_klass_or_reference() + : cp->tag_at(index).is_klass_reference()); + } + public: // Constructor ClassFileParser(ClassFileStream* st) { set_stream(st); } @@ -218,6 +248,14 @@ Handle class_loader, Handle protection_domain, symbolHandle& parsed_name, + TRAPS) { + return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD); + } + instanceKlassHandle parseClassFile(symbolHandle name, + Handle class_loader, + Handle protection_domain, + GrowableArray* cp_patches, + symbolHandle& parsed_name, TRAPS); // Verifier checks diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -937,6 +937,8 @@ Handle class_loader, Handle protection_domain, ClassFileStream* st, + KlassHandle host_klass, + GrowableArray* cp_patches, TRAPS) { symbolHandle parsed_name; @@ -953,10 +955,10 @@ instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, class_loader, protection_domain, + cp_patches, parsed_name, THREAD); - // We don't redefine the class, so we just need to clean up whether there // was an error or not (don't want to modify any system dictionary // data structures). @@ -973,6 +975,30 @@ } } + if (host_klass.not_null() && k.not_null()) { + assert(AnonymousClasses, ""); + // If it's anonymous, initialize it now, since nobody else will. + k->set_host_klass(host_klass()); + + { + MutexLocker mu_r(Compile_lock, THREAD); + + // Add to class hierarchy, initialize vtables, and do possible + // deoptimizations. + add_to_hierarchy(k, CHECK_NULL); // No exception, but can block + + // But, do not add to system dictionary. + } + + k->eager_initialize(THREAD); + + // notify jvmti + if (JvmtiExport::should_post_class_load()) { + assert(THREAD->is_Java_thread(), "thread->is_Java_thread()"); + JvmtiExport::post_class_load((JavaThread *) THREAD, k()); + } + } + return k(); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -228,6 +228,16 @@ Handle class_loader, Handle protection_domain, ClassFileStream* st, + TRAPS) { + KlassHandle nullHandle; + return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD); + } + static klassOop parse_stream(symbolHandle class_name, + Handle class_loader, + Handle protection_domain, + ClassFileStream* st, + KlassHandle host_klass, + GrowableArray* cp_patches, TRAPS); // Resolve from stream (called by jni_DefineClass and JVM_DefineClass) diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -1600,7 +1600,11 @@ types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long); verify_cp_type(index, cp, types, CHECK_VERIFY(this)); } - if (tag.is_string() || tag.is_unresolved_string()) { + if (tag.is_string() && cp->is_pseudo_string_at(index)) { + current_frame->push_stack( + VerificationType::reference_type( + vmSymbols::java_lang_Object()), CHECK_VERIFY(this)); + } else if (tag.is_string() || tag.is_unresolved_string()) { current_frame->push_stack( VerificationType::reference_type( vmSymbols::java_lang_String()), CHECK_VERIFY(this)); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp Fri Nov 21 08:09:11 2008 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +0,0 @@ -/* - * Copyright 2001-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -// CopyrightVersion 1.2 - -# include "incls/_precompiled.incl" -# include "incls/_concurrentGCThread.cpp.incl" - -bool ConcurrentGCThread::_should_terminate = false; -bool ConcurrentGCThread::_has_terminated = false; -int ConcurrentGCThread::_CGC_flag = CGC_nil; - -SuspendibleThreadSet ConcurrentGCThread::_sts; - -ConcurrentGCThread::ConcurrentGCThread() { - _sts.initialize(); -}; - -void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) { - MutexLockerEx x(Heap_lock, - Mutex::_no_safepoint_check_flag); - // warning("CGC: about to try stopping world"); - SafepointSynchronize::begin(); - // warning("CGC: successfully stopped world"); - op->do_void(); - SafepointSynchronize::end(); - // warning("CGC: successfully restarted world"); -} - -void ConcurrentGCThread::safepoint_synchronize() { - _sts.suspend_all(); -} - -void ConcurrentGCThread::safepoint_desynchronize() { - _sts.resume_all(); -} - -void ConcurrentGCThread::create_and_start() { - if (os::create_thread(this, os::cgc_thread)) { - // XXX: need to set this to low priority - // unless "agressive mode" set; priority - // should be just less than that of VMThread. - os::set_priority(this, NearMaxPriority); - if (!_should_terminate && !DisableStartThread) { - os::start_thread(this); - } - } -} - -void ConcurrentGCThread::initialize_in_thread() { - this->record_stack_base_and_size(); - this->initialize_thread_local_storage(); - this->set_active_handles(JNIHandleBlock::allocate_block()); - // From this time Thread::current() should be working. - assert(this == Thread::current(), "just checking"); -} - -void ConcurrentGCThread::wait_for_universe_init() { - MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); - while (!is_init_completed() && !_should_terminate) { - CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200); - } -} - -void ConcurrentGCThread::terminate() { - // Signal that it is terminated - { - MutexLockerEx mu(Terminator_lock, - Mutex::_no_safepoint_check_flag); - _has_terminated = true; - Terminator_lock->notify(); - } - - // Thread destructor usually does this.. - ThreadLocalStorage::set_thread(NULL); -} - - -void SuspendibleThreadSet::initialize_work() { - MutexLocker x(STS_init_lock); - if (!_initialized) { - _m = new Monitor(Mutex::leaf, - "SuspendibleThreadSetLock", true); - _async = 0; - _async_stop = false; - _async_stopped = 0; - _initialized = true; - } -} - -void SuspendibleThreadSet::join() { - initialize(); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); - _async++; - assert(_async > 0, "Huh."); -} - -void SuspendibleThreadSet::leave() { - assert(_initialized, "Must be initialized."); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - _async--; - assert(_async >= 0, "Huh."); - if (_async_stop) _m->notify_all(); -} - -void SuspendibleThreadSet::yield(const char* id) { - assert(_initialized, "Must be initialized."); - if (_async_stop) { - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - if (_async_stop) { - _async_stopped++; - assert(_async_stopped > 0, "Huh."); - if (_async_stopped == _async) { - if (ConcGCYieldTimeout > 0) { - double now = os::elapsedTime(); - guarantee((now - _suspend_all_start) * 1000.0 < - (double)ConcGCYieldTimeout, - "Long delay; whodunit?"); - } - } - _m->notify_all(); - while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag); - _async_stopped--; - assert(_async >= 0, "Huh"); - _m->notify_all(); - } - } -} - -void SuspendibleThreadSet::suspend_all() { - initialize(); // If necessary. - if (ConcGCYieldTimeout > 0) { - _suspend_all_start = os::elapsedTime(); - } - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - assert(!_async_stop, "Only one at a time."); - _async_stop = true; - while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag); -} - -void SuspendibleThreadSet::resume_all() { - assert(_initialized, "Must be initialized."); - MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); - assert(_async_stopped == _async, "Huh."); - _async_stop = false; - _m->notify_all(); -} - -static void _sltLoop(JavaThread* thread, TRAPS) { - SurrogateLockerThread* slt = (SurrogateLockerThread*)thread; - slt->loop(); -} - -SurrogateLockerThread::SurrogateLockerThread() : - JavaThread(&_sltLoop), - _monitor(Mutex::nonleaf, "SLTMonitor"), - _buffer(empty) -{} - -SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) { - klassOop k = - SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(), - true, CHECK_NULL); - instanceKlassHandle klass (THREAD, k); - instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); - - const char thread_name[] = "Surrogate Locker Thread (CMS)"; - Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL); - - // Initialize thread_oop to put it into the system threadGroup - Handle thread_group (THREAD, Universe::system_thread_group()); - JavaValue result(T_VOID); - JavaCalls::call_special(&result, thread_oop, - klass, - vmSymbolHandles::object_initializer_name(), - vmSymbolHandles::threadgroup_string_void_signature(), - thread_group, - string, - CHECK_NULL); - - SurrogateLockerThread* res; - { - MutexLocker mu(Threads_lock); - res = new SurrogateLockerThread(); - - // At this point it may be possible that no osthread was created for the - // JavaThread due to lack of memory. We would have to throw an exception - // in that case. However, since this must work and we do not allow - // exceptions anyway, check and abort if this fails. - if (res == NULL || res->osthread() == NULL) { - vm_exit_during_initialization("java.lang.OutOfMemoryError", - "unable to create new native thread"); - } - java_lang_Thread::set_thread(thread_oop(), res); - java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); - java_lang_Thread::set_daemon(thread_oop()); - - res->set_threadObj(thread_oop()); - Threads::add(res); - Thread::start(res); - } - os::yield(); // This seems to help with initial start-up of SLT - return res; -} - -void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) { - MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag); - assert(_buffer == empty, "Should be empty"); - assert(msg != empty, "empty message"); - _buffer = msg; - while (_buffer != empty) { - _monitor.notify(); - _monitor.wait(Mutex::_no_safepoint_check_flag); - } -} - -// ======= Surrogate Locker Thread ============= - -void SurrogateLockerThread::loop() { - BasicLock pll_basic_lock; - SLT_msg_type msg; - debug_only(unsigned int owned = 0;) - - while (/* !isTerminated() */ 1) { - { - MutexLocker x(&_monitor); - // Since we are a JavaThread, we can't be here at a safepoint. - assert(!SafepointSynchronize::is_at_safepoint(), - "SLT is a JavaThread"); - // wait for msg buffer to become non-empty - while (_buffer == empty) { - _monitor.notify(); - _monitor.wait(); - } - msg = _buffer; - } - switch(msg) { - case acquirePLL: { - instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock); - debug_only(owned++;) - break; - } - case releaseAndNotifyPLL: { - assert(owned > 0, "Don't have PLL"); - instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock); - debug_only(owned--;) - break; - } - case empty: - default: { - guarantee(false,"Unexpected message in _buffer"); - break; - } - } - { - MutexLocker x(&_monitor); - // Since we are a JavaThread, we can't be here at a safepoint. - assert(!SafepointSynchronize::is_at_safepoint(), - "SLT is a JavaThread"); - _buffer = empty; - _monitor.notify(); - } - } - assert(!_monitor.owned_by_self(), "Should unlock before exit."); -} - - -// ===== STS Access From Outside CGCT ===== - -void ConcurrentGCThread::stsYield(const char* id) { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.yield(id); -} - -bool ConcurrentGCThread::stsShouldYield() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - return _sts.should_yield(); -} - -void ConcurrentGCThread::stsJoin() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.join(); -} - -void ConcurrentGCThread::stsLeave() { - assert( Thread::current()->is_ConcurrentGC_thread(), - "only a conc GC thread can call this" ); - _sts.leave(); -} diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp Fri Nov 21 08:09:11 2008 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - * Copyright 2001-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -class VoidClosure; - -// A SuspendibleThreadSet is (obviously) a set of threads that can be -// suspended. A thread can join and later leave the set, and periodically -// yield. If some thread (not in the set) requests, via suspend_all, that -// the threads be suspended, then the requesting thread is blocked until -// all the threads in the set have yielded or left the set. (Threads may -// not enter the set when an attempted suspension is in progress.) The -// suspending thread later calls resume_all, allowing the suspended threads -// to continue. - -class SuspendibleThreadSet { - Monitor* _m; - int _async; - bool _async_stop; - int _async_stopped; - bool _initialized; - double _suspend_all_start; - - void initialize_work(); - - public: - SuspendibleThreadSet() : _initialized(false) {} - - // Add the current thread to the set. May block if a suspension - // is in progress. - void join(); - // Removes the current thread from the set. - void leave(); - // Returns "true" iff an suspension is in progress. - bool should_yield() { return _async_stop; } - // Suspends the current thread if a suspension is in progress (for - // the duration of the suspension.) - void yield(const char* id); - // Return when all threads in the set are suspended. - void suspend_all(); - // Allow suspended threads to resume. - void resume_all(); - // Redundant initializations okay. - void initialize() { - // Double-check dirty read idiom. - if (!_initialized) initialize_work(); - } -}; - - -class ConcurrentGCThread: public NamedThread { - friend class VMStructs; - -protected: - static bool _should_terminate; - static bool _has_terminated; - - enum CGC_flag_type { - CGC_nil = 0x0, - CGC_dont_suspend = 0x1, - CGC_CGC_safepoint = 0x2, - CGC_VM_safepoint = 0x4 - }; - - static int _CGC_flag; - - static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; } - static int set_CGC_flag(int b) { return _CGC_flag |= b; } - static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; } - - void stopWorldAndDo(VoidClosure* op); - - // All instances share this one set. - static SuspendibleThreadSet _sts; - - // Create and start the thread (setting it's priority high.) - void create_and_start(); - - // Do initialization steps in the thread: record stack base and size, - // init thread local storage, set JNI handle block. - void initialize_in_thread(); - - // Wait until Universe::is_fully_initialized(); - void wait_for_universe_init(); - - // Record that the current thread is terminating, and will do more - // concurrent work. - void terminate(); - -public: - // Constructor - - ConcurrentGCThread(); - ~ConcurrentGCThread() {} // Exists to call NamedThread destructor. - - // Tester - bool is_ConcurrentGC_thread() const { return true; } - - static void safepoint_synchronize(); - static void safepoint_desynchronize(); - - // All overridings should probably do _sts::yield, but we allow - // overriding for distinguished debugging messages. Default is to do - // nothing. - virtual void yield() {} - - bool should_yield() { return _sts.should_yield(); } - - // they are prefixed by sts since there are already yield() and - // should_yield() (non-static) methods in this class and it was an - // easy way to differentiate them. - static void stsYield(const char* id); - static bool stsShouldYield(); - static void stsJoin(); - static void stsLeave(); - -}; - -// The SurrogateLockerThread is used by concurrent GC threads for -// manipulating Java monitors, in particular, currently for -// manipulating the pending_list_lock. XXX -class SurrogateLockerThread: public JavaThread { - friend class VMStructs; - public: - enum SLT_msg_type { - empty = 0, // no message - acquirePLL, // acquire pending list lock - releaseAndNotifyPLL // notify and release pending list lock - }; - private: - // the following are shared with the CMSThread - SLT_msg_type _buffer; // communication buffer - Monitor _monitor; // monitor controlling buffer - BasicLock _basicLock; // used for PLL locking - - public: - static SurrogateLockerThread* make(TRAPS); - - SurrogateLockerThread(); - - bool is_hidden_from_external_view() const { return true; } - - void loop(); // main method - - void manipulatePLL(SLT_msg_type msg); - -}; diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -30,7 +30,7 @@ _perm(perm), _lock(NULL) {} -PtrQueue::~PtrQueue() { +void PtrQueue::flush() { if (!_perm && _buf != NULL) { if (_index == _sz) { // No work to do. @@ -41,8 +41,9 @@ _buf[byte_index_to_index((int)i)] = NULL; } qset()->enqueue_complete_buffer(_buf); - _buf = NULL; } + _buf = NULL; + _index = 0; } } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -62,7 +62,9 @@ // given PtrQueueSet. PtrQueue(PtrQueueSet*, bool perm = false); // Release any contained resources. - ~PtrQueue(); + void flush(); + // Calls flush() when destroyed. + ~PtrQueue() { flush(); } // Associate a lock with a ptr queue. void set_lock(Mutex* lock) { _lock = lock; } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -90,10 +90,10 @@ */ bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0); - ssize_t allowed_deadspace = 0; + size_t allowed_deadspace = 0; if (skip_dead) { - int ratio = allowed_dead_ratio(); - allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize; + const size_t ratio = allowed_dead_ratio(); + allowed_deadspace = space()->capacity_in_words() * ratio / 100; } // Fetch the current destination decorator @@ -271,10 +271,10 @@ dest->set_compaction_top(compact_top); } -bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words, - HeapWord* q, size_t deadlength) { - allowed_deadspace_words -= deadlength; - if (allowed_deadspace_words >= 0) { +bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words, + HeapWord* q, size_t deadlength) { + if (allowed_deadspace_words >= deadlength) { + allowed_deadspace_words -= deadlength; oop(q)->set_mark(markOopDesc::prototype()->set_marked()); const size_t aligned_min_int_array_size = align_object_size(typeArrayOopDesc::header_size(T_INT)); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -39,14 +39,16 @@ HeapWord* _first_dead; HeapWord* _end_of_live; HeapWord* _compaction_top; - unsigned int _allowed_dead_ratio; + size_t _allowed_dead_ratio; - bool insert_deadspace(ssize_t& allowed_deadspace_words, HeapWord* q, size_t word_len); + bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q, + size_t word_len); public: PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array, - unsigned int allowed_dead_ratio) : - _space(space), _start_array(start_array), _allowed_dead_ratio(allowed_dead_ratio) { } + size_t allowed_dead_ratio) : + _space(space), _start_array(start_array), + _allowed_dead_ratio(allowed_dead_ratio) { } // During a compacting collection, we need to collapse objects into // spaces in a given order. We want to fill space A, space B, and so @@ -57,14 +59,14 @@ static PSMarkSweepDecorator* destination_decorator(); // Accessors - MutableSpace* space() { return _space; } - ObjectStartArray* start_array() { return _start_array; } + MutableSpace* space() { return _space; } + ObjectStartArray* start_array() { return _start_array; } - HeapWord* compaction_top() { return _compaction_top; } - void set_compaction_top(HeapWord* value) { _compaction_top = value; } + HeapWord* compaction_top() { return _compaction_top; } + void set_compaction_top(HeapWord* value) { _compaction_top = value; } - unsigned int allowed_dead_ratio() { return _allowed_dead_ratio; } - void set_allowed_dead_ratio(unsigned int value) { _allowed_dead_ratio = value; } + size_t allowed_dead_ratio() { return _allowed_dead_ratio; } + void set_allowed_dead_ratio(size_t value) { _allowed_dead_ratio = value; } // Work methods void adjust_pointers(); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/includeDB_gc_parallel --- a/hotspot/src/share/vm/includeDB_gc_parallel Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/includeDB_gc_parallel Fri Nov 21 15:10:14 2008 -0500 @@ -30,6 +30,12 @@ compiledICHolderKlass.cpp oop.pcgc.inline.hpp +constantPoolKlass.cpp cardTableRS.hpp +constantPoolKlass.cpp oop.pcgc.inline.hpp +constantPoolKlass.cpp psPromotionManager.inline.hpp +constantPoolKlass.cpp psScavenge.inline.hpp +constantPoolKlass.cpp parOopClosures.inline.hpp + genCollectedHeap.cpp concurrentMarkSweepThread.hpp genCollectedHeap.cpp vmCMSOperations.hpp diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/memory/space.cpp --- a/hotspot/src/share/vm/memory/space.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/memory/space.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -997,11 +997,11 @@ } -int TenuredSpace::allowed_dead_ratio() const { +size_t TenuredSpace::allowed_dead_ratio() const { return MarkSweepDeadRatio; } -int ContigPermSpace::allowed_dead_ratio() const { +size_t ContigPermSpace::allowed_dead_ratio() const { return PermMarkSweepDeadRatio; } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/memory/space.hpp --- a/hotspot/src/share/vm/memory/space.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/memory/space.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -421,7 +421,7 @@ // The maximum percentage of objects that can be dead in the compacted // live part of a compacted space ("deadwood" support.) - virtual int allowed_dead_ratio() const { return 0; }; + virtual size_t allowed_dead_ratio() const { return 0; }; // Some contiguous spaces may maintain some data structures that should // be updated whenever an allocation crosses a boundary. This function @@ -507,7 +507,7 @@ \ size_t allowed_deadspace = 0; \ if (skip_dead) { \ - int ratio = allowed_dead_ratio(); \ + const size_t ratio = allowed_dead_ratio(); \ allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \ } \ \ @@ -1079,7 +1079,7 @@ friend class VMStructs; protected: // Mark sweep support - int allowed_dead_ratio() const; + size_t allowed_dead_ratio() const; public: // Constructor TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray, @@ -1094,7 +1094,7 @@ friend class VMStructs; protected: // Mark sweep support - int allowed_dead_ratio() const; + size_t allowed_dead_ratio() const; public: // Constructor ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) : diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/memory/tenuredGeneration.hpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -73,7 +73,6 @@ // Mark sweep support void compute_new_size(); - int allowed_dead_ratio() const; virtual void gc_prologue(bool full); virtual void gc_epilogue(bool full); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/constantPoolKlass.cpp --- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -35,6 +35,7 @@ c->set_tags(NULL); c->set_cache(NULL); c->set_pool_holder(NULL); + c->set_flags(0); // only set to non-zero if constant pool is merged by RedefineClasses c->set_orig_length(0); // all fields are initialized; needed for GC @@ -261,10 +262,32 @@ void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { assert(obj->is_constantPool(), "should be constant pool"); + constantPoolOop cp = (constantPoolOop) obj; + if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) { + oop* base = (oop*)cp->base(); + for (int i = 0; i < cp->length(); ++i, ++base) { + if (cp->tag_at(i).is_string()) { + if (PSScavenge::should_scavenge(base)) { + pm->claim_or_forward_breadth(base); + } + } + } + } } void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { assert(obj->is_constantPool(), "should be constant pool"); + constantPoolOop cp = (constantPoolOop) obj; + if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) { + oop* base = (oop*)cp->base(); + for (int i = 0; i < cp->length(); ++i, ++base) { + if (cp->tag_at(i).is_string()) { + if (PSScavenge::should_scavenge(base)) { + pm->claim_or_forward_depth(base); + } + } + } + } } #endif // SERIALGC @@ -278,6 +301,11 @@ assert(obj->is_constantPool(), "must be constantPool"); Klass::oop_print_on(obj, st); constantPoolOop cp = constantPoolOop(obj); + if (cp->flags() != 0) { + st->print(" - flags : 0x%x", cp->flags()); + if (cp->has_pseudo_string()) st->print(" has_pseudo_string"); + st->cr(); + } // Temp. remove cache so we can do lookups with original indicies. constantPoolCacheHandle cache (THREAD, cp->cache()); @@ -302,7 +330,11 @@ break; case JVM_CONSTANT_UnresolvedString : case JVM_CONSTANT_String : - anObj = cp->string_at(index, CATCH); + if (cp->is_pseudo_string_at(index)) { + anObj = cp->pseudo_string_at(index); + } else { + anObj = cp->string_at(index, CATCH); + } anObj->print_value_on(st); st->print(" {0x%lx}", (address)anObj); break; @@ -382,8 +414,12 @@ "should be symbol or instance"); } if (cp->tag_at(i).is_string()) { - guarantee((*base)->is_perm(), "should be in permspace"); - guarantee((*base)->is_instance(), "should be instance"); + if (!cp->has_pseudo_string()) { + guarantee((*base)->is_perm(), "should be in permspace"); + guarantee((*base)->is_instance(), "should be instance"); + } else { + // can be non-perm, can be non-instance (array) + } } base++; } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/constantPoolOop.cpp --- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -25,6 +25,18 @@ # include "incls/_precompiled.incl" # include "incls/_constantPoolOop.cpp.incl" +void constantPoolOopDesc::set_flag_at(FlagBit fb) { + const int MAX_STATE_CHANGES = 2; + for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) { + int oflags = _flags; + int nflags = oflags | (1 << (int)fb); + if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags) + return; + } + assert(false, "failed to cmpxchg flags"); + _flags |= (1 << (int)fb); // better than nothing +} + klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and @@ -333,8 +345,10 @@ oop entry = *(obj_at_addr(which)); if (entry->is_symbol()) { return ((symbolOop)entry)->as_C_string(); + } else if (java_lang_String::is_instance(entry)) { + return java_lang_String::as_utf8_string(entry); } else { - return java_lang_String::as_utf8_string(entry); + return (char*)""; } } @@ -385,6 +399,19 @@ } +bool constantPoolOopDesc::is_pseudo_string_at(int which) { + oop entry = *(obj_at_addr(which)); + if (entry->is_symbol()) + // Not yet resolved, but it will resolve to a string. + return false; + else if (java_lang_String::is_instance(entry)) + return false; // actually, it might be a non-interned or non-perm string + else + // truly pseudo + return true; +} + + bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k, int which) { // Names are interned, so we can compare symbolOops directly diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/constantPoolOop.hpp --- a/hotspot/src/share/vm/oops/constantPoolOop.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -41,6 +41,7 @@ typeArrayOop _tags; // the tag array describing the constant pool's contents constantPoolCacheOop _cache; // the cache holding interpreter runtime information klassOop _pool_holder; // the corresponding class + int _flags; // a few header bits to describe contents for GC int _length; // number of elements in the array // only set to non-zero if constant pool is merged by RedefineClasses int _orig_length; @@ -49,6 +50,16 @@ void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); } void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); } + enum FlagBit { + FB_has_pseudo_string = 2 + }; + + int flags() const { return _flags; } + void set_flags(int f) { _flags = f; } + bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; } + void set_flag_at(FlagBit fb); + // no clear_flag_at function; they only increase + private: intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); } oop* tags_addr() { return (oop*)&_tags; } @@ -82,6 +93,9 @@ public: typeArrayOop tags() const { return _tags; } + bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); } + void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); } + // Klass holding pool klassOop pool_holder() const { return _pool_holder; } void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); } @@ -272,6 +286,27 @@ return string_at_impl(h_this, which, CHECK_NULL); } + // A "pseudo-string" is an non-string oop that has found is way into + // a String entry. + // Under AnonymousClasses this can happen if the user patches a live + // object into a CONSTANT_String entry of an anonymous class. + // Method oops internally created for method handles may also + // use pseudo-strings to link themselves to related metaobjects. + + bool is_pseudo_string_at(int which); + + oop pseudo_string_at(int which) { + assert(tag_at(which).is_string(), "Corrupted constant pool"); + return *obj_at_addr(which); + } + + void pseudo_string_at_put(int which, oop x) { + assert(AnonymousClasses, ""); + set_pseudo_string(); // mark header + assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool"); + string_at_put(which, x); // this works just fine + } + // only called when we are sure a string entry is already resolved (via an // earlier string_at call. oop resolved_string_at(int which) { @@ -293,6 +328,7 @@ // UTF8 char* representation was chosen to avoid conversion of // java_lang_Strings at resolved entries into symbolOops // or vice versa. + // Caller is responsible for checking for pseudo-strings. char* string_at_noresolve(int which); jint name_and_type_at(int which) { diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -147,6 +147,10 @@ oop _class_loader; // Protection domain. oop _protection_domain; + // Host class, which grants its access privileges to this class also. + // This is only non-null for an anonymous class (AnonymousClasses enabled). + // The host class is either named, or a previously loaded anonymous class. + klassOop _host_klass; // Class signers. objArrayOop _signers; // Name of source file containing this klass, NULL if not specified. @@ -375,6 +379,11 @@ oop protection_domain() { return _protection_domain; } void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); } + // host class + oop host_klass() const { return _host_klass; } + void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); } + bool is_anonymous() const { return _host_klass != NULL; } + // signers objArrayOop signers() const { return _signers; } void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); } @@ -709,6 +718,7 @@ oop* adr_constants() const { return (oop*)&this->_constants;} oop* adr_class_loader() const { return (oop*)&this->_class_loader;} oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;} + oop* adr_host_klass() const { return (oop*)&this->_host_klass;} oop* adr_signers() const { return (oop*)&this->_signers;} oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;} oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;} diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/instanceKlassKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -81,6 +81,7 @@ MarkSweep::mark_and_push(ik->adr_source_debug_extension()); MarkSweep::mark_and_push(ik->adr_inner_classes()); MarkSweep::mark_and_push(ik->adr_protection_domain()); + MarkSweep::mark_and_push(ik->adr_host_klass()); MarkSweep::mark_and_push(ik->adr_signers()); MarkSweep::mark_and_push(ik->adr_generic_signature()); MarkSweep::mark_and_push(ik->adr_class_annotations()); @@ -120,6 +121,7 @@ PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension()); PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); + PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); PSParallelCompact::mark_and_push(cm, ik->adr_signers()); PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature()); PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); @@ -159,6 +161,7 @@ blk->do_oop(ik->adr_constants()); blk->do_oop(ik->adr_class_loader()); blk->do_oop(ik->adr_protection_domain()); + blk->do_oop(ik->adr_host_klass()); blk->do_oop(ik->adr_signers()); blk->do_oop(ik->adr_source_file_name()); blk->do_oop(ik->adr_source_debug_extension()); @@ -211,6 +214,8 @@ if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_protection_domain(); if (mr.contains(adr)) blk->do_oop(adr); + adr = ik->adr_host_klass(); + if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_signers(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_source_file_name(); @@ -260,6 +265,7 @@ MarkSweep::adjust_pointer(ik->adr_constants()); MarkSweep::adjust_pointer(ik->adr_class_loader()); MarkSweep::adjust_pointer(ik->adr_protection_domain()); + MarkSweep::adjust_pointer(ik->adr_host_klass()); MarkSweep::adjust_pointer(ik->adr_signers()); MarkSweep::adjust_pointer(ik->adr_source_file_name()); MarkSweep::adjust_pointer(ik->adr_source_debug_extension()); @@ -295,6 +301,11 @@ pm->claim_or_forward_breadth(pd_addr); } + oop* hk_addr = ik->adr_host_klass(); + if (PSScavenge::should_scavenge(hk_addr)) { + pm->claim_or_forward_breadth(hk_addr); + } + oop* sg_addr = ik->adr_signers(); if (PSScavenge::should_scavenge(sg_addr)) { pm->claim_or_forward_breadth(sg_addr); @@ -318,6 +329,11 @@ pm->claim_or_forward_depth(pd_addr); } + oop* hk_addr = ik->adr_host_klass(); + if (PSScavenge::should_scavenge(hk_addr)) { + pm->claim_or_forward_depth(hk_addr); + } + oop* sg_addr = ik->adr_signers(); if (PSScavenge::should_scavenge(sg_addr)) { pm->claim_or_forward_depth(sg_addr); @@ -421,6 +437,7 @@ ik->set_constants(NULL); ik->set_class_loader(NULL); ik->set_protection_domain(NULL); + ik->set_host_klass(NULL); ik->set_signers(NULL); ik->set_source_file_name(NULL); ik->set_source_debug_extension(NULL); @@ -526,6 +543,7 @@ st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr(); st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr(); st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr(); + st->print(" - host class: "); ik->host_klass()->print_value_on(st); st->cr(); st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr(); if (ik->source_file_name() != NULL) { st->print(" - source file: "); @@ -626,7 +644,7 @@ ik->_verify_count = Universe::verify_count(); #endif // Verify that klass is present in SystemDictionary - if (ik->is_loaded()) { + if (ik->is_loaded() && !ik->is_anonymous()) { symbolHandle h_name (thread, ik->name()); Handle h_loader (thread, ik->class_loader()); Handle h_obj(thread, obj); @@ -764,6 +782,9 @@ if (ik->protection_domain() != NULL) { guarantee(ik->protection_domain()->is_oop(), "should be oop"); } + if (ik->host_klass() != NULL) { + guarantee(ik->host_klass()->is_oop(), "should be oop"); + } if (ik->signers() != NULL) { guarantee(ik->signers()->is_objArray(), "should be obj array"); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/oops/klass.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -478,6 +478,24 @@ const char* Klass::external_name() const { + if (oop_is_instance()) { + instanceKlass* ik = (instanceKlass*) this; + if (ik->is_anonymous()) { + assert(AnonymousClasses, ""); + intptr_t hash = ik->java_mirror()->identity_hash(); + char hash_buf[40]; + sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash); + size_t hash_len = strlen(hash_buf); + + size_t result_len = name()->utf8_length(); + char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); + name()->as_klass_external_name(result, (int) result_len + 1); + assert(strlen(result) == result_len, ""); + strcpy(result + result_len, hash_buf); + assert(strlen(result) == result_len + hash_len, ""); + return result; + } + } return name()->as_klass_external_name(); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -256,10 +256,10 @@ develop(intx, PrintIdealGraphPort, 4444, \ "Ideal graph printer to network port") \ \ - develop(ccstr, PrintIdealGraphAddress, "127.0.0.1", \ + notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1", \ "IP address to connect to visualizer") \ \ - develop(ccstr, PrintIdealGraphFile, NULL, \ + notproduct(ccstr, PrintIdealGraphFile, NULL, \ "File to dump ideal graph to. If set overrides the " \ "use of the network") \ \ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/opto/macro.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -1673,7 +1673,6 @@ if (klass_node == NULL) { Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); - klass_node->init_req(0, ctrl); } Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type()); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/opto/parse.hpp --- a/hotspot/src/share/vm/opto/parse.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/opto/parse.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -175,7 +175,7 @@ bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); } bool is_invariant_local(uint i) const { const JVMState* jvms = start_map()->jvms(); - if (!jvms->is_loc(i)) return false; + if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false; return flow()->is_invariant_local(i - jvms->locoff()); } bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -744,6 +744,7 @@ // common code for JVM_DefineClass() and JVM_DefineClassWithSource() static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) { + if (source == NULL) source = "__JVM_DefineClass__"; // Since exceptions can be thrown, class initialization can take place // if name is NULL no check for class name in .class stream has to be made. @@ -782,7 +783,7 @@ JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)) JVMWrapper2("JVM_DefineClass %s", name); - return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD); + return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD); JVM_END diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/prims/jvm.h Fri Nov 21 15:10:14 2008 -0500 @@ -422,6 +422,14 @@ const jbyte *buf, jsize len, jobject pd, const char *source); +/* Define a class with a source (MLVM) */ +JNIEXPORT jclass JNICALL +JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader, + const jbyte *buf, jsize len, jobject pd, + const char *source, + // same args as JVM_DefineClassWithSource to this point + jobjectArray constants); + /* * Reflection support functions */ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -837,6 +837,163 @@ } UNSAFE_END +#define DAC_Args CLS"[B["OBJ +// define a class but do not make it known to the class loader or system dictionary +// - host_class: supplies context for linkage, access control, protection domain, and class loader +// - data: bytes of a class file, a raw memory address (length gives the number of bytes) +// - cp_patches: where non-null entries exist, they replace corresponding CP entries in data + +// When you load an anonymous class U, it works as if you changed its name just before loading, +// to a name that you will never use again. Since the name is lost, no other class can directly +// link to any member of U. Just after U is loaded, the only way to use it is reflectively, +// through java.lang.Class methods like Class.newInstance. + +// Access checks for linkage sites within U continue to follow the same rules as for named classes. +// The package of an anonymous class is given by the package qualifier on the name under which it was loaded. +// An anonymous class also has special privileges to access any member of its host class. +// This is the main reason why this loading operation is unsafe. The purpose of this is to +// allow language implementations to simulate "open classes"; a host class in effect gets +// new code when an anonymous class is loaded alongside it. A less convenient but more +// standard way to do this is with reflection, which can also be set to ignore access +// restrictions. + +// Access into an anonymous class is possible only through reflection. Therefore, there +// are no special access rules for calling into an anonymous class. The relaxed access +// rule for the host class is applied in the opposite direction: A host class reflectively +// access one of its anonymous classes. + +// If you load the same bytecodes twice, you get two different classes. You can reload +// the same bytecodes with or without varying CP patches. + +// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1. +// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is). +// The CONSTANT_Class entry for that name can be patched to refer directly to U1. + +// This allows, for example, U2 to use U1 as a superclass or super-interface, or as +// an outer class (so that U2 is an anonymous inner class of anonymous U1). +// It is not possible for a named class, or an older anonymous class, to refer by +// name (via its CP) to a newer anonymous class. + +// CP patching may also be used to modify (i.e., hack) the names of methods, classes, +// or type descriptors used in the loaded anonymous class. + +// Finally, CP patching may be used to introduce "live" objects into the constant pool, +// instead of "dead" strings. A compiled statement like println((Object)"hello") can +// be changed to println(greeting), where greeting is an arbitrary object created before +// the anonymous class is loaded. This is useful in dynamic languages, in which +// various kinds of metaobjects must be introduced as constants into bytecode. +// Note the cast (Object), which tells the verifier to expect an arbitrary object, +// not just a literal string. For such ldc instructions, the verifier uses the +// type Object instead of String, if the loaded constant is not in fact a String. + +static oop +Unsafe_DefineAnonymousClass_impl(JNIEnv *env, + jclass host_class, jbyteArray data, jobjectArray cp_patches_jh, + HeapWord* *temp_alloc, + TRAPS) { + + if (UsePerfData) { + ClassLoader::unsafe_defineClassCallCounter()->inc(); + } + + if (data == NULL) { + THROW_0(vmSymbols::java_lang_NullPointerException()); + } + + jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length(); + jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord); + HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length); + if (body == NULL) { + THROW_0(vmSymbols::java_lang_OutOfMemoryError()); + } + + // caller responsible to free it: + (*temp_alloc) = body; + + { + jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0); + Copy::conjoint_words((HeapWord*) array_base, body, word_length); + } + + u1* class_bytes = (u1*) body; + int class_bytes_length = (int) length; + if (class_bytes_length < 0) class_bytes_length = 0; + if (class_bytes == NULL + || host_class == NULL + || length != class_bytes_length) + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); + + objArrayHandle cp_patches_h; + if (cp_patches_jh != NULL) { + oop p = JNIHandles::resolve_non_null(cp_patches_jh); + if (!p->is_objArray()) + THROW_0(vmSymbols::java_lang_IllegalArgumentException()); + cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p); + } + + KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class))); + const char* host_source = host_klass->external_name(); + Handle host_loader(THREAD, host_klass->class_loader()); + Handle host_domain(THREAD, host_klass->protection_domain()); + + GrowableArray* cp_patches = NULL; + if (cp_patches_h.not_null()) { + int alen = cp_patches_h->length(); + for (int i = alen-1; i >= 0; i--) { + oop p = cp_patches_h->obj_at(i); + if (p != NULL) { + Handle patch(THREAD, p); + if (cp_patches == NULL) + cp_patches = new GrowableArray(i+1, i+1, Handle()); + cp_patches->at_put(i, patch); + } + } + } + + ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source); + + instanceKlassHandle anon_klass; + { + symbolHandle no_class_name; + klassOop anonk = SystemDictionary::parse_stream(no_class_name, + host_loader, host_domain, + &st, host_klass, cp_patches, + CHECK_NULL); + if (anonk == NULL) return NULL; + anon_klass = instanceKlassHandle(THREAD, anonk); + } + + // let caller initialize it as needed... + + return anon_klass->java_mirror(); +} + +UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh)) +{ + UnsafeWrapper("Unsafe_DefineAnonymousClass"); + ResourceMark rm(THREAD); + + HeapWord* temp_alloc = NULL; + + jobject res_jh = NULL; + + { oop res_oop = Unsafe_DefineAnonymousClass_impl(env, + host_class, data, cp_patches_jh, + &temp_alloc, THREAD); + if (res_oop != NULL) + res_jh = JNIHandles::make_local(env, res_oop); + } + + // try/finally clause: + if (temp_alloc != NULL) { + FREE_C_HEAP_ARRAY(HeapWord, temp_alloc); + } + + return (jclass) res_jh; +} +UNSAFE_END + + UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) UnsafeWrapper("Unsafe_MonitorEnter"); @@ -1292,6 +1449,9 @@ {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)} }; +JNINativeMethod anonk_methods[] = { + {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)}, +}; #undef CC #undef FN_PTR @@ -1354,6 +1514,15 @@ } } } + if (AnonymousClasses) { + env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod)); + if (env->ExceptionOccurred()) { + if (PrintMiscellaneous && (Verbose || WizardMode)) { + tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found."); + } + env->ExceptionClear(); + } + } int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod)); if (env->ExceptionOccurred()) { if (PrintMiscellaneous && (Verbose || WizardMode)) { diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -493,7 +493,7 @@ develop(bool, DeoptimizeALot, false, \ "deoptimize at every exit from the runtime system") \ \ - develop(ccstrlist, DeoptimizeOnlyAt, "", \ + notproduct(ccstrlist, DeoptimizeOnlyAt, "", \ "a comma separated list of bcis to deoptimize at") \ \ product(bool, DeoptimizeRandom, false, \ @@ -2792,7 +2792,7 @@ product(intx, TargetSurvivorRatio, 50, \ "Desired percentage of survivor space used after scavenge") \ \ - product(intx, MarkSweepDeadRatio, 5, \ + product(uintx, MarkSweepDeadRatio, 5, \ "Percentage (0-100) of the old gen allowed as dead wood." \ "Serial mark sweep treats this as both the min and max value." \ "CMS uses this value only if it falls back to mark sweep." \ @@ -2801,7 +2801,7 @@ "either completely full or completely empty. Par compact also" \ "has a smaller default value; see arguments.cpp.") \ \ - product(intx, PermMarkSweepDeadRatio, 20, \ + product(uintx, PermMarkSweepDeadRatio, 20, \ "Percentage (0-100) of the perm gen allowed as dead wood." \ "See MarkSweepDeadRatio for collector-specific comments.") \ \ @@ -3230,6 +3230,9 @@ "Skip assert() and verify() which page-in unwanted shared " \ "objects. ") \ \ + product(bool, AnonymousClasses, false, \ + "support sun.misc.Unsafe.defineAnonymousClass") \ + \ product(bool, TaggedStackInterpreter, false, \ "Insert tags in interpreter execution stack for oopmap generaion")\ \ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/perfMemory.cpp --- a/hotspot/src/share/vm/runtime/perfMemory.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/perfMemory.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -25,6 +25,14 @@ # include "incls/_precompiled.incl" # include "incls/_perfMemory.cpp.incl" +// Prefix of performance data file. +const char PERFDATA_NAME[] = "hsperfdata"; + +// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating +// character will be included in the sizeof(PERFDATA_NAME) operation. +static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) + + UINT_CHARS + 1; + char* PerfMemory::_start = NULL; char* PerfMemory::_end = NULL; char* PerfMemory::_top = NULL; diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/perfMemory.hpp --- a/hotspot/src/share/vm/runtime/perfMemory.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/perfMemory.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -95,7 +95,7 @@ } PerfDataEntry; // Prefix of performance data file. -static const char PERFDATA_NAME[] = "hsperfdata"; +extern const char PERFDATA_NAME[]; // UINT_CHARS contains the number of characters holding a process id // (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value @@ -103,11 +103,6 @@ // string. static const size_t UINT_CHARS = 10; -// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating -// character will be included in the sizeof(PERFDATA_NAME) operation. -static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) + - UINT_CHARS + 1; - /* the PerfMemory class manages creation, destruction, * and allocation of the PerfData region. */ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/reflection.cpp --- a/hotspot/src/share/vm/runtime/reflection.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -456,10 +456,32 @@ return can_relax_access_check_for(current_class, new_class, classloader_only); } +static bool under_host_klass(instanceKlass* ik, klassOop host_klass) { + DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); + for (;;) { + klassOop hc = (klassOop) ik->host_klass(); + if (hc == NULL) return false; + if (hc == host_klass) return true; + ik = instanceKlass::cast(hc); + + // There's no way to make a host class loop short of patching memory. + // Therefore there cannot be a loop here unles there's another bug. + // Still, let's check for it. + assert(--inf_loop_check > 0, "no host_klass loop"); + } +} + bool Reflection::can_relax_access_check_for( klassOop accessor, klassOop accessee, bool classloader_only) { instanceKlass* accessor_ik = instanceKlass::cast(accessor); instanceKlass* accessee_ik = instanceKlass::cast(accessee); + + // If either is on the other's host_klass chain, access is OK, + // because one is inside the other. + if (under_host_klass(accessor_ik, accessee) || + under_host_klass(accessee_ik, accessor)) + return true; + if (RelaxAccessControlCheck || (accessor_ik->major_version() < JAVA_1_5_VERSION && accessee_ik->major_version() < JAVA_1_5_VERSION)) { diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -1422,6 +1422,7 @@ thread->clear_pending_exception(); } + // For any new cleanup additions, please check to see if they need to be applied to // cleanup_failed_attach_current_thread as well. void JavaThread::exit(bool destroy_vm, ExitType exit_type) { @@ -1592,39 +1593,62 @@ JvmtiExport::cleanup_thread(this); } +#ifndef SERIALGC + // We must flush G1-related buffers before removing a thread from + // the list of active threads. + if (UseG1GC) { + flush_barrier_queues(); + } +#endif + // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread Threads::remove(this); } +#ifndef SERIALGC +// Flush G1-related queues. +void JavaThread::flush_barrier_queues() { + satb_mark_queue().flush(); + dirty_card_queue().flush(); +} +#endif + void JavaThread::cleanup_failed_attach_current_thread() { - - if (get_thread_profiler() != NULL) { - get_thread_profiler()->disengage(); - ResourceMark rm; - get_thread_profiler()->print(get_thread_name()); - } - - if (active_handles() != NULL) { - JNIHandleBlock* block = active_handles(); - set_active_handles(NULL); - JNIHandleBlock::release_block(block); - } - - if (free_handle_block() != NULL) { - JNIHandleBlock* block = free_handle_block(); - set_free_handle_block(NULL); - JNIHandleBlock::release_block(block); - } - - if (UseTLAB) { - tlab().make_parsable(true); // retire TLAB, if any - } - - Threads::remove(this); - delete this; + if (get_thread_profiler() != NULL) { + get_thread_profiler()->disengage(); + ResourceMark rm; + get_thread_profiler()->print(get_thread_name()); + } + + if (active_handles() != NULL) { + JNIHandleBlock* block = active_handles(); + set_active_handles(NULL); + JNIHandleBlock::release_block(block); + } + + if (free_handle_block() != NULL) { + JNIHandleBlock* block = free_handle_block(); + set_free_handle_block(NULL); + JNIHandleBlock::release_block(block); + } + + if (UseTLAB) { + tlab().make_parsable(true); // retire TLAB, if any + } + +#ifndef SERIALGC + if (UseG1GC) { + flush_barrier_queues(); + } +#endif + + Threads::remove(this); + delete this; } + + JavaThread* JavaThread::active() { Thread* thread = ThreadLocalStorage::thread(); assert(thread != NULL, "just checking"); diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -793,6 +793,8 @@ DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards. // Set of all such queues. static DirtyCardQueueSet _dirty_card_queue_set; + + void flush_barrier_queues(); #endif // !SERIALGC friend class VMThread; diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/utilities/array.hpp --- a/hotspot/src/share/vm/utilities/array.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/utilities/array.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -40,11 +40,18 @@ _length = 0; _data = NULL; DEBUG_ONLY(init_nesting();) + // client may call initialize, at most once } ResourceArray(size_t esize, int length) { + DEBUG_ONLY(_data = NULL); + initialize(esize, length); + } + + void initialize(size_t esize, int length) { assert(length >= 0, "illegal length"); + assert(_data == NULL, "must be new object"); _length = length; _data = resource_allocate_bytes(esize * length); DEBUG_ONLY(init_nesting();) @@ -111,7 +118,10 @@ /* creation */ \ array_name() : base_class() {} \ array_name(const int length) : base_class(esize, length) {} \ - array_name(const int length, const etype fx) : base_class(esize, length) { \ + array_name(const int length, const etype fx) { initialize(length, fx); } \ + void initialize(const int length) { base_class::initialize(esize, length); } \ + void initialize(const int length, const etype fx) { \ + initialize(length); \ for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \ } \ \ @@ -157,16 +167,29 @@ \ public: \ /* creation */ \ - stack_name() : array_name() { _size = 0; } \ - stack_name(const int size) : array_name(size){ _length = 0; _size = size; } \ - stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; } \ + stack_name() : array_name() { _size = 0; } \ + stack_name(const int size) { initialize(size); } \ + stack_name(const int size, const etype fx) { initialize(size, fx); } \ + void initialize(const int size, const etype fx) { \ + _size = size; \ + array_name::initialize(size, fx); \ + /* _length == size, allocation and size are the same */ \ + } \ + void initialize(const int size) { \ + _size = size; \ + array_name::initialize(size); \ + _length = 0; /* reset length to zero; _size records the allocation */ \ + } \ \ /* standard operations */ \ int size() const { return _size; } \ \ - void push(const etype x) { \ - if (length() >= size()) expand(esize, length(), _size); \ - ((etype*)_data)[_length++] = x; \ + int push(const etype x) { \ + int len = length(); \ + if (len >= size()) expand(esize, len, _size); \ + ((etype*)_data)[len] = x; \ + _length = len+1; \ + return len; \ } \ \ etype pop() { \ @@ -235,7 +258,7 @@ int capacity() const { return size(); } \ void clear() { truncate(0); } \ void trunc_to(const int length) { truncate(length); } \ - void append(const etype x) { push(x); } \ + int append(const etype x) { return push(x); } \ void appendAll(const stack_name* stack) { push_all(stack); } \ etype last() const { return top(); } \ }; \ diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/utilities/constantTag.hpp --- a/hotspot/src/share/vm/utilities/constantTag.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/utilities/constantTag.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -71,6 +71,7 @@ bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; } bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); } + bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); } bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); } bool is_symbol() const { return is_utf8(); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/utilities/debug.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -567,7 +567,7 @@ } // the InlineCacheBuffer is using stubs generated into a buffer blob if (InlineCacheBuffer::contains(addr)) { - tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr); + tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); return; } VtableStub* v = VtableStubs::stub_containing(addr); @@ -595,7 +595,7 @@ return; } - if (Universe::heap()->is_in_reserved(addr)) { + if (Universe::heap()->is_in(addr)) { HeapWord* p = Universe::heap()->block_start(addr); bool print = false; // If we couldn't find it it just may mean that heap wasn't parseable @@ -621,24 +621,28 @@ } return; } + } else if (Universe::heap()->is_in_reserved(addr)) { + tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr); + return; } + if (JNIHandles::is_global_handle((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr); return; } if (JNIHandles::is_weak_global_handle((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr); return; } if (JNIHandleBlock::any_contains((jobject) addr)) { - tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr); + tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr); return; } for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { - // Check for priviledge stack + // Check for privilege stack if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) { - tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread); + tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread); return; } // If the addr is a java thread print information about that. @@ -659,7 +663,7 @@ return; } - tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr); + tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr); } diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/utilities/growableArray.hpp --- a/hotspot/src/share/vm/utilities/growableArray.hpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/utilities/growableArray.hpp Fri Nov 21 15:10:14 2008 -0500 @@ -111,6 +111,12 @@ } void* raw_allocate(int elementSize); + + // some uses pass the Thread explicitly for speed (4990299 tuning) + void* raw_allocate(Thread* thread, int elementSize) { + assert(on_stack(), "fast ResourceObj path only"); + return (void*)resource_allocate_bytes(thread, elementSize * _max); + } }; template class GrowableArray : public GenericGrowableArray { @@ -121,6 +127,11 @@ void raw_at_put_grow(int i, const E& p, const E& fill); void clear_and_deallocate(); public: + GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) { + _data = (E*)raw_allocate(thread, sizeof(E)); + for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); + } + GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) { _data = (E*)raw_allocate(sizeof(E)); for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E(); @@ -159,10 +170,12 @@ void print(); - void append(const E& elem) { + int append(const E& elem) { check_nesting(); if (_len == _max) grow(_len); - _data[_len++] = elem; + int idx = _len++; + _data[idx] = elem; + return idx; } void append_if_missing(const E& elem) { diff -r 776009a04496 -r bb12ee0dbc91 hotspot/src/share/vm/utilities/hashtable.cpp --- a/hotspot/src/share/vm/utilities/hashtable.cpp Fri Nov 21 08:09:11 2008 -0800 +++ b/hotspot/src/share/vm/utilities/hashtable.cpp Fri Nov 21 15:10:14 2008 -0500 @@ -43,9 +43,11 @@ entry = _free_list; _free_list = _free_list->next(); } else { - const int block_size = 500; - if (_first_free_entry == _end_block) { + if (_first_free_entry + _entry_size >= _end_block) { + int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries)); int len = _entry_size * block_size; + len = 1 << log2_intptr(len); // round down to power of 2 + assert(len >= _entry_size, ""); _first_free_entry = NEW_C_HEAP_ARRAY(char, len); _end_block = _first_free_entry + len; } @@ -53,6 +55,7 @@ _first_free_entry += _entry_size; } + assert(_entry_size % HeapWordSize == 0, ""); entry->set_hash(hashValue); return entry; } diff -r 776009a04496 -r bb12ee0dbc91 jaxp/.hgtags --- a/jaxp/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/jaxp/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36 af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37 e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38 +831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 jaxws/.hgtags --- a/jaxws/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/jaxws/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36 a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37 9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38 +077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 jdk/.hgtags --- a/jdk/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ 134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36 14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37 cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38 +4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 jdk/make/netbeans/jmx/build.xml --- a/jdk/make/netbeans/jmx/build.xml Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/make/netbeans/jmx/build.xml Fri Nov 21 15:10:14 2008 -0500 @@ -44,13 +44,13 @@ - - + @@ -58,13 +58,13 @@ - + @@ -96,7 +96,7 @@ - + - - @@ -131,7 +131,7 @@ - @@ -144,7 +144,7 @@ - + diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java --- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Fri Nov 21 15:10:14 2008 -0500 @@ -141,7 +141,7 @@ } private final Runnable callback; - private ScheduledFuture scheduled; // If null, the lease has expired. + private ScheduledFuture scheduled; // If null, the lease has expired. private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java --- a/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java Fri Nov 21 15:10:14 2008 -0500 @@ -128,7 +128,7 @@ }; private final Callable doRenew; - private ScheduledFuture future; + private ScheduledFuture future; private boolean closed = false; private long nextRenewTime; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Fri Nov 21 15:10:14 2008 -0500 @@ -247,7 +247,7 @@ MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { - Class theClass; + Class theClass; if (className == null) { final RuntimeException wrapped = @@ -327,7 +327,7 @@ // ------------------------------ // ------------------------------ - Class theClass = object.getClass(); + Class theClass = object.getClass(); Introspector.checkCompliance(theClass); @@ -808,9 +808,8 @@ // on each specific attribute // allowedAttributes = new AttributeList(attributes.size()); - for (Iterator i = attributes.iterator(); i.hasNext();) { + for (Attribute attribute : attributes.asList()) { try { - Attribute attribute = (Attribute) i.next(); checkMBeanPermission(mbeanServerName, classname, attribute.getName(), name, "setAttribute"); allowedAttributes.add(attribute); @@ -1857,7 +1856,7 @@ } } - private static void checkMBeanTrustPermission(final Class theClass) + private static void checkMBeanTrustPermission(final Class theClass) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -136,14 +136,14 @@ new Hashtable(10); // from javax.management.loading.DefaultLoaderRepository - public final Class loadClass(String className) + public final Class loadClass(String className) throws ClassNotFoundException { return loadClass(loaders, className, null, null); } // from javax.management.loading.DefaultLoaderRepository - public final Class loadClassWithout(ClassLoader without, String className) + public final Class loadClassWithout(ClassLoader without, String className) throws ClassNotFoundException { if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) { MBEANSERVER_LOGGER.logp(Level.FINER, @@ -167,7 +167,7 @@ } - public final Class loadClassBefore(ClassLoader stop, String className) + public final Class loadClassBefore(ClassLoader stop, String className) throws ClassNotFoundException { if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) { MBEANSERVER_LOGGER.logp(Level.FINER, @@ -187,10 +187,10 @@ } - private Class loadClass(final LoaderEntry list[], - final String className, - final ClassLoader without, - final ClassLoader stop) + private Class loadClass(final LoaderEntry list[], + final String className, + final ClassLoader without, + final ClassLoader stop) throws ClassNotFoundException { final int size = list.length; for(int i=0; i getOpenReturnType() { return returnMapping.getOpenType(); } - OpenType[] getOpenParameterTypes() { - final OpenType[] types = new OpenType[paramMappings.length]; + OpenType[] getOpenParameterTypes() { + final OpenType[] types = new OpenType[paramMappings.length]; for (int i = 0; i < paramMappings.length; i++) types[i] = paramMappings[i].getOpenType(); return types; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Fri Nov 21 15:10:14 2008 -0500 @@ -26,7 +26,8 @@ package com.sun.jmx.mbeanserver; import static com.sun.jmx.mbeanserver.Util.*; -import java.lang.annotation.ElementType; +import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName; + import javax.management.openmbean.MXBeanMappingClass; import static javax.management.openmbean.SimpleType.*; @@ -120,7 +121,7 @@ */ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory { static abstract class NonNullMXBeanMapping extends MXBeanMapping { - NonNullMXBeanMapping(Type javaType, OpenType openType) { + NonNullMXBeanMapping(Type javaType, OpenType openType) { super(javaType, openType); } @@ -195,15 +196,15 @@ static { /* Set up the mappings for Java types that map to SimpleType. */ - final OpenType[] simpleTypes = { + final OpenType[] simpleTypes = { BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE, DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING, VOID, }; for (int i = 0; i < simpleTypes.length; i++) { - final OpenType t = simpleTypes[i]; - Class c; + final OpenType t = simpleTypes[i]; + Class c; try { c = Class.forName(t.getClassName(), false, ObjectName.class.getClassLoader()); @@ -224,7 +225,7 @@ if (primitiveType != void.class) { final Class primitiveArrayType = Array.newInstance(primitiveType, 0).getClass(); - final OpenType primitiveArrayOpenType = + final OpenType primitiveArrayOpenType = ArrayType.getPrimitiveArrayType(primitiveArrayType); final MXBeanMapping primitiveArrayMapping = new IdentityMapping(primitiveArrayType, @@ -247,8 +248,10 @@ public synchronized MXBeanMapping mappingForType(Type objType, MXBeanMappingFactory factory) throws OpenDataException { - if (inProgress.containsKey(objType)) - throw new OpenDataException("Recursive data structure"); + if (inProgress.containsKey(objType)) { + throw new OpenDataException( + "Recursive data structure, including " + typeName(objType)); + } MXBeanMapping mapping; @@ -259,6 +262,8 @@ inProgress.put(objType, objType); try { mapping = makeMapping(objType, factory); + } catch (OpenDataException e) { + throw openDataException("Cannot convert type: " + typeName(objType), e); } finally { inProgress.remove(objType); } @@ -285,13 +290,13 @@ Type componentType = ((GenericArrayType) objType).getGenericComponentType(); return makeArrayOrCollectionMapping(objType, componentType, factory); - } else if (objType instanceof Class) { + } else if (objType instanceof Class) { Class objClass = (Class) objType; if (objClass.isEnum()) { // Huge hack to avoid compiler warnings here. The ElementType // parameter is ignored but allows us to obtain a type variable // T that matches >. - return makeEnumMapping((Class) objClass, ElementType.class); + return makeEnumMapping((Class) objClass, ElementType.class); } else if (objClass.isArray()) { Type componentType = objClass.getComponentType(); return makeArrayOrCollectionMapping(objClass, componentType, @@ -354,7 +359,7 @@ } private static > MXBeanMapping - makeEnumMapping(Class enumClass, Class fake) { + makeEnumMapping(Class enumClass, Class fake) { return new EnumMapping(Util.>cast(enumClass)); } @@ -411,17 +416,17 @@ MXBeanMappingFactory factory) throws OpenDataException { - final String objTypeName = objType.toString(); + final String objTypeName = typeName(objType); final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory); final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory); - final OpenType keyOpenType = keyMapping.getOpenType(); - final OpenType valueOpenType = valueMapping.getOpenType(); + final OpenType keyOpenType = keyMapping.getOpenType(); + final OpenType valueOpenType = valueMapping.getOpenType(); final CompositeType rowType = new CompositeType(objTypeName, objTypeName, keyValueArray, keyValueArray, - new OpenType[] {keyOpenType, valueOpenType}); + new OpenType[] {keyOpenType, valueOpenType}); final TabularType tabularType = new TabularType(objTypeName, objTypeName, rowType, keyArray); return new TabularMapping(objType, sortedMap, tabularType, @@ -440,8 +445,8 @@ final Type rawType = objType.getRawType(); - if (rawType instanceof Class) { - Class c = (Class) rawType; + if (rawType instanceof Class) { + Class c = (Class) rawType; if (c == List.class || c == Set.class || c == SortedSet.class) { Type[] actuals = objType.getActualTypeArguments(); assert(actuals.length == 1); @@ -468,7 +473,7 @@ return new MXBeanRefMapping(t); } - private MXBeanMapping makeCompositeMapping(Class c, + private MXBeanMapping makeCompositeMapping(Class c, MXBeanMappingFactory factory) throws OpenDataException { @@ -514,7 +519,7 @@ final Method[] getters = new Method[nitems]; final String[] itemNames = new String[nitems]; - final OpenType[] openTypes = new OpenType[nitems]; + final OpenType[] openTypes = new OpenType[nitems]; int i = 0; for (Map.Entry entry : getterMap.entrySet()) { itemNames[i] = entry.getKey(); @@ -546,7 +551,7 @@ can be directly represented by an ArrayType, and an int needs no mapping because reflection takes care of it. */ private static final class IdentityMapping extends NonNullMXBeanMapping { - IdentityMapping(Type targetType, OpenType openType) { + IdentityMapping(Type targetType, OpenType openType) { super(targetType, openType); } @@ -576,7 +581,7 @@ @Override final Object toNonNullOpenValue(Object value) { - return ((Enum) value).name(); + return ((Enum) value).name(); } @Override @@ -595,7 +600,7 @@ private static final class ArrayMapping extends NonNullMXBeanMapping { ArrayMapping(Type targetType, - ArrayType openArrayType, Class openArrayClass, + ArrayType openArrayType, Class openArrayClass, MXBeanMapping elementMapping) { super(targetType, openArrayType); this.elementMapping = elementMapping; @@ -623,7 +628,7 @@ if (javaType instanceof GenericArrayType) { componentType = ((GenericArrayType) javaType).getGenericComponentType(); - } else if (javaType instanceof Class && + } else if (javaType instanceof Class && ((Class) javaType).isArray()) { componentType = ((Class) javaType).getComponentType(); } else { @@ -651,8 +656,8 @@ private static final class CollectionMapping extends NonNullMXBeanMapping { CollectionMapping(Type targetType, - ArrayType openArrayType, - Class openArrayClass, + ArrayType openArrayType, + Class openArrayClass, MXBeanMapping elementMapping) { super(targetType, openArrayType); this.elementMapping = elementMapping; @@ -662,26 +667,28 @@ and all Sets to TreeSet. (TreeSet because it is a SortedSet, so works for both Set and SortedSet.) */ Type raw = ((ParameterizedType) targetType).getRawType(); - Class c = (Class) raw; + Class c = (Class) raw; + final Class collC; if (c == List.class) - collectionClass = ArrayList.class; + collC = ArrayList.class; else if (c == Set.class) - collectionClass = HashSet.class; + collC = HashSet.class; else if (c == SortedSet.class) - collectionClass = TreeSet.class; + collC = TreeSet.class; else { // can't happen assert(false); - collectionClass = null; + collC = null; } + collectionClass = Util.cast(collC); } @Override final Object toNonNullOpenValue(Object value) throws OpenDataException { - final Collection valueCollection = (Collection) value; - if (valueCollection instanceof SortedSet) { - Comparator comparator = - ((SortedSet) valueCollection).comparator(); + final Collection valueCollection = (Collection) value; + if (valueCollection instanceof SortedSet) { + Comparator comparator = + ((SortedSet) valueCollection).comparator(); if (comparator != null) { final String msg = "Cannot convert SortedSet with non-null comparator: " + @@ -725,7 +732,7 @@ elementMapping.checkReconstructible(); } - private final Class collectionClass; + private final Class> collectionClass; private final MXBeanMapping elementMapping; } @@ -794,8 +801,8 @@ @Override final Object toNonNullOpenValue(Object value) throws OpenDataException { final Map valueMap = cast(value); - if (valueMap instanceof SortedMap) { - Comparator comparator = ((SortedMap) valueMap).comparator(); + if (valueMap instanceof SortedMap) { + Comparator comparator = ((SortedMap) valueMap).comparator(); if (comparator != null) { final String msg = "Cannot convert SortedMap with non-null comparator: " + @@ -806,7 +813,7 @@ final TabularType tabularType = (TabularType) getOpenType(); final TabularData table = new TabularDataSupport(tabularType); final CompositeType rowType = tabularType.getRowType(); - for (Map.Entry entry : valueMap.entrySet()) { + for (Map.Entry entry : valueMap.entrySet()) { final Object openKey = keyMapping.toOpenValue(entry.getKey()); final Object openValue = valueMapping.toOpenValue(entry.getValue()); final CompositeData row; @@ -852,7 +859,7 @@ } private final class CompositeMapping extends NonNullMXBeanMapping { - CompositeMapping(Class targetClass, + CompositeMapping(Class targetClass, CompositeType compositeType, String[] itemNames, Method[] getters, @@ -901,7 +908,7 @@ if (compositeBuilder != null) return; - Class targetClass = (Class) getJavaType(); + Class targetClass = (Class) getJavaType(); /* In this 2D array, each subarray is a set of builders where there is no point in consulting the ones after the first if the first refuses. */ @@ -924,6 +931,7 @@ concatenating each Builder's explanation of why it isn't applicable. */ final StringBuilder whyNots = new StringBuilder(); + Throwable possibleCause = null; find: for (CompositeBuilder[] relatedBuilders : builders) { for (int i = 0; i < relatedBuilders.length; i++) { @@ -933,6 +941,9 @@ foundBuilder = builder; break find; } + Throwable cause = builder.possibleCause(); + if (cause != null) + possibleCause = cause; if (whyNot.length() > 0) { if (whyNots.length() > 0) whyNots.append("; "); @@ -943,10 +954,12 @@ } } if (foundBuilder == null) { - final String msg = + String msg = "Do not know how to make a " + targetClass.getName() + " from a CompositeData: " + whyNots; - throw new InvalidObjectException(msg); + if (possibleCause != null) + msg += ". Remaining exceptions show a POSSIBLE cause."; + throw invalidObjectException(msg, possibleCause); } compositeBuilder = foundBuilder; } @@ -973,7 +986,7 @@ /** Converts from a CompositeData to an instance of the targetClass. */ private static abstract class CompositeBuilder { - CompositeBuilder(Class targetClass, String[] itemNames) { + CompositeBuilder(Class targetClass, String[] itemNames) { this.targetClass = targetClass; this.itemNames = itemNames; } @@ -994,6 +1007,16 @@ abstract String applicable(Method[] getters) throws InvalidObjectException; + /** If the subclass returns an explanation of why it is not applicable, + it can additionally indicate an exception with details. This is + potentially confusing, because the real problem could be that one + of the other subclasses is supposed to be applicable but isn't. + But the advantage of less information loss probably outweighs the + disadvantage of possible confusion. */ + Throwable possibleCause() { + return null; + } + abstract Object fromCompositeData(CompositeData cd, String[] itemNames, MXBeanMapping[] converters) @@ -1008,7 +1031,7 @@ private static final class CompositeBuilderViaFrom extends CompositeBuilder { - CompositeBuilderViaFrom(Class targetClass, String[] itemNames) { + CompositeBuilderViaFrom(Class targetClass, String[] itemNames) { super(targetClass, itemNames); } @@ -1018,8 +1041,7 @@ Class targetClass = getTargetClass(); try { Method fromMethod = - targetClass.getMethod("from", - new Class[] {CompositeData.class}); + targetClass.getMethod("from", CompositeData.class); if (!Modifier.isStatic(fromMethod.getModifiers())) { final String msg = @@ -1030,8 +1052,8 @@ if (fromMethod.getReturnType() != getTargetClass()) { final String msg = "Method from(CompositeData) returns " + - fromMethod.getReturnType().getName() + - " not " + targetClass.getName(); + typeName(fromMethod.getReturnType()) + + " not " + typeName(targetClass); throw new InvalidObjectException(msg); } @@ -1071,7 +1093,7 @@ If all the getters are OK, then the "applicable" method will return an empty string and the other builders will be tried. */ private static class CompositeBuilderCheckGetters extends CompositeBuilder { - CompositeBuilderCheckGetters(Class targetClass, String[] itemNames, + CompositeBuilderCheckGetters(Class targetClass, String[] itemNames, MXBeanMapping[] getterConverters) { super(targetClass, itemNames); this.getterConverters = getterConverters; @@ -1082,6 +1104,7 @@ try { getterConverters[i].checkReconstructible(); } catch (InvalidObjectException e) { + possibleCause = e; return "method " + getters[i].getName() + " returns type " + "that cannot be mapped back from OpenData"; } @@ -1089,6 +1112,11 @@ return ""; } + @Override + Throwable possibleCause() { + return possibleCause; + } + final Object fromCompositeData(CompositeData cd, String[] itemNames, MXBeanMapping[] converters) { @@ -1096,6 +1124,7 @@ } private final MXBeanMapping[] getterConverters; + private Throwable possibleCause; } /** Builder for when the target class has a setter for every getter. */ @@ -1115,7 +1144,7 @@ Method[] setters = new Method[getters.length]; for (int i = 0; i < getters.length; i++) { Method getter = getters[i]; - Class returnType = getter.getReturnType(); + Class returnType = getter.getReturnType(); String name = propertyName(getter); String setterName = "set" + name; Method setter; @@ -1163,7 +1192,7 @@ private static final class CompositeBuilderViaConstructor extends CompositeBuilder { - CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) { + CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) { super(targetClass, itemNames); } @@ -1171,7 +1200,7 @@ final Class propertyNamesClass = ConstructorProperties.class; - Class targetClass = getTargetClass(); + Class targetClass = getTargetClass(); Constructor[] constrs = targetClass.getConstructors(); // Applicable if and only if there are any annotated constructors @@ -1226,10 +1255,16 @@ for (int i = 0; i < propertyNames.length; i++) { String propertyName = propertyNames[i]; if (!getterMap.containsKey(propertyName)) { - final String msg = + String msg = "@ConstructorProperties includes name " + propertyName + - " which does not correspond to a property: " + - constr; + " which does not correspond to a property"; + for (String getterName : getterMap.keySet()) { + if (getterName.equalsIgnoreCase(propertyName)) { + msg += " (differs only in case from property " + + getterName + ")"; + } + } + msg += ": " + constr; throw new InvalidObjectException(msg); } int getterIndex = getterMap.get(propertyName); @@ -1384,12 +1419,12 @@ private static final class CompositeBuilderViaProxy extends CompositeBuilder { - CompositeBuilderViaProxy(Class targetClass, String[] itemNames) { + CompositeBuilderViaProxy(Class targetClass, String[] itemNames) { super(targetClass, itemNames); } String applicable(Method[] getters) { - Class targetClass = getTargetClass(); + Class targetClass = getTargetClass(); if (!targetClass.isInterface()) return "not an interface"; Set methods = @@ -1401,7 +1436,7 @@ String bad = null; for (Method m : methods) { String mname = m.getName(); - Class[] mparams = m.getParameterTypes(); + Class[] mparams = m.getParameterTypes(); try { Method om = Object.class.getMethod(mname, mparams); if (!Modifier.isPublic(om.getModifiers())) @@ -1422,10 +1457,10 @@ final Object fromCompositeData(CompositeData cd, String[] itemNames, MXBeanMapping[] converters) { - final Class targetClass = getTargetClass(); + final Class targetClass = getTargetClass(); return Proxy.newProxyInstance(targetClass.getClassLoader(), - new Class[] {targetClass}, + new Class[] {targetClass}, new CompositeDataInvocationHandler(cd)); } } @@ -1447,9 +1482,9 @@ return openDataException(cause.getMessage(), cause); } - static void mustBeComparable(Class collection, Type element) + static void mustBeComparable(Class collection, Type element) throws OpenDataException { - if (!(element instanceof Class) + if (!(element instanceof Class) || !Comparable.class.isAssignableFrom((Class) element)) { final String msg = "Parameter class " + element + " of " + diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java Fri Nov 21 15:10:14 2008 -0500 @@ -115,7 +115,7 @@ * Dynamic MBeans, false otherwise. * **/ - public static final boolean isDynamic(final Class c) { + public static final boolean isDynamic(final Class c) { // Check if the MBean implements the DynamicMBean interface return javax.management.DynamicMBean.class.isAssignableFrom(c); } @@ -134,7 +134,7 @@ * MBeanServer. * **/ - public static void testCreation(Class c) + public static void testCreation(Class c) throws NotCompliantMBeanException { // Check if the class is a concrete class final int mods = c.getModifiers(); @@ -143,7 +143,7 @@ } // Check if the MBean has a public constructor - final Constructor[] consList = c.getConstructors(); + final Constructor[] consList = c.getConstructors(); if (consList.length == 0) { throw new NotCompliantMBeanException("MBean class must have public constructor"); } @@ -253,7 +253,7 @@ * @exception NotCompliantMBeanException The specified class is not a * JMX compliant MBean */ - public static MBeanInfo testCompliance(Class baseClass) + public static MBeanInfo testCompliance(Class baseClass) throws NotCompliantMBeanException { // ------------------------------ @@ -267,7 +267,7 @@ return testCompliance(baseClass, null); } - public static void testComplianceMXBeanInterface(Class interfaceClass, + public static void testComplianceMXBeanInterface(Class interfaceClass, MXBeanMappingFactory factory) throws NotCompliantMBeanException { MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass); @@ -596,10 +596,10 @@ ss[i] = (String) annotationToField(xx[i]); return ss; } - if (x instanceof Class) + if (x instanceof Class) return ((Class) x).getName(); - if (x instanceof Enum) - return ((Enum) x).name(); + if (x instanceof Enum) + return ((Enum) x).name(); // The only other possibility is that the value is another // annotation, or that the language has evolved since this code // was written. We don't allow for either of those currently. diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java Fri Nov 21 15:10:14 2008 -0500 @@ -33,6 +33,7 @@ import java.security.Permission; import java.security.PrivilegedExceptionAction; import java.util.Iterator; +import java.util.List; import java.util.Set; import java.util.logging.Level; @@ -1144,7 +1145,7 @@ // This call requires MBeanPermission 'getClassLoaderRepository' final ClassLoaderRepository clr = getClassLoaderRepository(); - Class theClass; + Class theClass; try { if (clr == null) throw new ClassNotFoundException(className); theClass = clr.loadClass(className); @@ -1457,23 +1458,22 @@ */ private AttributeList cloneAttributeList(AttributeList list) { if (list != null) { + List alist = list.asList(); if (!list.getClass().equals(AttributeList.class)) { // Create new attribute list // - AttributeList newList = new AttributeList(list.size()); + AttributeList newList = new AttributeList(alist.size()); // Iterate through list and replace non JMX attributes // - for (Iterator i = list.iterator(); i.hasNext(); ) { - Attribute attribute = (Attribute) i.next(); + for (Attribute attribute : alist) newList.add(cloneAttribute(attribute)); - } return newList; } else { // Iterate through list and replace non JMX attributes // - for (int i = 0; i < list.size(); i++) { - Attribute attribute = (Attribute) list.get(i); + for (int i = 0; i < alist.size(); i++) { + Attribute attribute = alist.get(i); if (!attribute.getClass().equals(Attribute.class)) { list.set(i, cloneAttribute(attribute)); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Fri Nov 21 15:10:14 2008 -0500 @@ -70,7 +70,7 @@ * instantiate an MBean of this class in the MBeanServer. * e.g. it must have a public constructor, be a concrete class... */ - public void testCreation(Class c) throws NotCompliantMBeanException { + public void testCreation(Class c) throws NotCompliantMBeanException { Introspector.testCreation(c); } @@ -78,10 +78,10 @@ * Loads the class with the specified name using this object's * Default Loader Repository. **/ - public Class findClassWithDefaultLoaderRepository(String className) + public Class findClassWithDefaultLoaderRepository(String className) throws ReflectionException { - Class theClass; + Class theClass; if (className == null) { throw new RuntimeOperationsException(new IllegalArgumentException("The class name cannot be null"), @@ -105,7 +105,7 @@ * Gets the class for the specified class name using the MBean * Interceptor's classloader */ - public Class findClass(String className, ClassLoader loader) + public Class findClass(String className, ClassLoader loader) throws ReflectionException { return loadClass(className,loader); @@ -115,7 +115,7 @@ * Gets the class for the specified class name using the specified * class loader */ - public Class findClass(String className, ObjectName aLoader) + public Class findClass(String className, ObjectName aLoader) throws ReflectionException, InstanceNotFoundException { if (aLoader == null) @@ -140,14 +140,14 @@ * Return an array of Class corresponding to the given signature, using * the specified class loader. */ - public Class[] findSignatureClasses(String signature[], - ClassLoader loader) - throws ReflectionException { + public Class[] findSignatureClasses(String signature[], + ClassLoader loader) + throws ReflectionException { if (signature == null) return null; final ClassLoader aLoader = loader; final int length= signature.length; - final Class tab[]=new Class[length]; + final Class tab[]=new Class[length]; if (length == 0) return tab; try { @@ -156,7 +156,7 @@ // forth) // - final Class primCla = primitiveClasses.get(signature[i]); + final Class primCla = primitiveClasses.get(signature[i]); if (primCla != null) { tab[i] = primCla; continue; @@ -203,14 +203,14 @@ * Instantiates an object given its class, using its empty constructor. * The call returns a reference to the newly created object. */ - public Object instantiate(Class theClass) + public Object instantiate(Class theClass) throws ReflectionException, MBeanException { Object moi; // ------------------------------ // ------------------------------ - Constructor cons = findConstructor(theClass, null); + Constructor cons = findConstructor(theClass, null); if (cons == null) { throw new ReflectionException(new NoSuchMethodException("No such constructor")); @@ -257,14 +257,14 @@ * signature of its constructor The call returns a reference to * the newly created object. */ - public Object instantiate(Class theClass, Object params[], + public Object instantiate(Class theClass, Object params[], String signature[], ClassLoader loader) throws ReflectionException, MBeanException { // Instantiate the new object // ------------------------------ // ------------------------------ - final Class[] tab; + final Class[] tab; Object moi; try { // Build the signature of the method @@ -283,7 +283,7 @@ } // Query the metadata service to get the right constructor - Constructor cons = findConstructor(theClass, tab); + Constructor cons = findConstructor(theClass, tab); if (cons == null) { throw new ReflectionException(new @@ -407,7 +407,7 @@ throw new RuntimeOperationsException(new IllegalArgumentException(), "Null className passed in parameter"); } - Class theClass; + Class theClass; if (loaderName == null) { // Load the class using the agent class loader theClass = findClass(className, loader); @@ -547,7 +547,7 @@ throws ReflectionException, MBeanException { - Class theClass = findClassWithDefaultLoaderRepository(className); + Class theClass = findClassWithDefaultLoaderRepository(className); return instantiate(theClass, params, signature, loader); } @@ -595,7 +595,7 @@ // ------------------------------ // ------------------------------ - Class theClass; + Class theClass; if (loaderName == null) { theClass = findClass(className, loader); @@ -617,10 +617,10 @@ * Load a class with the specified loader, or with this object * class loader if the specified loader is null. **/ - static Class loadClass(String className, ClassLoader loader) + static Class loadClass(String className, ClassLoader loader) throws ReflectionException { - Class theClass; + Class theClass; if (className == null) { throw new RuntimeOperationsException(new IllegalArgumentException("The class name cannot be null"), @@ -647,15 +647,15 @@ * Load the classes specified in the signature with the given loader, * or with this object class loader. **/ - static Class[] loadSignatureClasses(String signature[], - ClassLoader loader) + static Class[] loadSignatureClasses(String signature[], + ClassLoader loader) throws ReflectionException { if (signature == null) return null; final ClassLoader aLoader = (loader==null?MBeanInstantiator.class.getClassLoader():loader); final int length= signature.length; - final Class tab[]=new Class[length]; + final Class tab[]=new Class[length]; if (length == 0) return tab; try { @@ -664,7 +664,7 @@ // forth) // - final Class primCla = primitiveClasses.get(signature[i]); + final Class primCla = primitiveClasses.get(signature[i]); if (primCla != null) { tab[i] = primCla; continue; @@ -710,9 +710,9 @@ private static final Map> primitiveClasses = Util.newMap(); static { - for (Class c : new Class[] {byte.class, short.class, int.class, - long.class, float.class, double.class, - char.class, boolean.class}) + for (Class c : new Class[] {byte.class, short.class, int.class, + long.class, float.class, double.class, + char.class, boolean.class}) primitiveClasses.put(c.getName(), c); } } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java Fri Nov 21 15:10:14 2008 -0500 @@ -160,7 +160,7 @@ // matched to the corresponding Java type, except when that // type is primitive. Type t = m.getGenericParameterTypes()[paramNo]; - return (!(t instanceof Class) || !((Class) t).isPrimitive()); + return (!(t instanceof Class) || !((Class) t).isPrimitive()); } else { Object v; try { @@ -354,7 +354,7 @@ } } - private static Descriptor typeDescriptor(OpenType openType, + private static Descriptor typeDescriptor(OpenType openType, Type originalType) { return new ImmutableDescriptor( new String[] {"openType", @@ -380,37 +380,37 @@ if (type instanceof GenericArrayType) { return canUseOpenInfo( ((GenericArrayType) type).getGenericComponentType()); - } else if (type instanceof Class && ((Class) type).isArray()) { + } else if (type instanceof Class && ((Class) type).isArray()) { return canUseOpenInfo( ((Class) type).getComponentType()); } - return (!(type instanceof Class && ((Class) type).isPrimitive())); + return (!(type instanceof Class && ((Class) type).isPrimitive())); } private static String originalTypeString(Type type) { - if (type instanceof Class) - return ((Class) type).getName(); + if (type instanceof Class) + return ((Class) type).getName(); else - return genericTypeString(type); + return typeName(type); } - private static String genericTypeString(Type type) { + static String typeName(Type type) { if (type instanceof Class) { Class c = (Class) type; if (c.isArray()) - return genericTypeString(c.getComponentType()) + "[]"; + return typeName(c.getComponentType()) + "[]"; else return c.getName(); } else if (type instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) type; - return genericTypeString(gat.getGenericComponentType()) + "[]"; + return typeName(gat.getGenericComponentType()) + "[]"; } else if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; StringBuilder sb = new StringBuilder(); - sb.append(genericTypeString(pt.getRawType())).append("<"); + sb.append(typeName(pt.getRawType())).append("<"); String sep = ""; for (Type t : pt.getActualTypeArguments()) { - sb.append(sep).append(genericTypeString(t)); + sb.append(sep).append(typeName(t)); sep = ", "; } return sb.append(">").toString(); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java Fri Nov 21 15:10:14 2008 -0500 @@ -54,7 +54,8 @@ this.loader = theLoader; } - protected Class resolveClass(ObjectStreamClass aClass) + @Override + protected Class resolveClass(ObjectStreamClass aClass) throws IOException, ClassNotFoundException { if (loader == null) { return super.resolveClass(aClass); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java Fri Nov 21 15:10:14 2008 -0500 @@ -47,16 +47,16 @@ public SecureClassLoaderRepository(ClassLoaderRepository clr) { this.clr=clr; } - public final Class loadClass(String className) + public final Class loadClass(String className) throws ClassNotFoundException { return clr.loadClass(className); } - public final Class loadClassWithout(ClassLoader loader, + public final Class loadClassWithout(ClassLoader loader, String className) throws ClassNotFoundException { return clr.loadClassWithout(loader,className); } - public final Class loadClassBefore(ClassLoader loader, + public final Class loadClassBefore(ClassLoader loader, String className) throws ClassNotFoundException { return clr.loadClassBefore(loader,className); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Fri Nov 21 15:10:14 2008 -0500 @@ -669,7 +669,7 @@ } public static Set cloneSet(Set set) { - if (set instanceof SortedSet) { + if (set instanceof SortedSet) { @SuppressWarnings("unchecked") SortedSet sset = (SortedSet) set; set = new TreeSet(sset.comparator()); @@ -680,7 +680,7 @@ } public static Set equivalentEmptySet(Set set) { - if (set instanceof SortedSet) { + if (set instanceof SortedSet) { @SuppressWarnings("unchecked") SortedSet sset = (SortedSet) set; set = new TreeSet(sset.comparator()); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java Fri Nov 21 15:10:14 2008 -0500 @@ -118,9 +118,9 @@ public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof IdentityWeakReference)) + if (!(o instanceof IdentityWeakReference)) return false; - IdentityWeakReference wr = (IdentityWeakReference) o; + IdentityWeakReference wr = (IdentityWeakReference) o; Object got = get(); return (got != null && got == wr.get()); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java Fri Nov 21 15:10:14 2008 -0500 @@ -120,7 +120,7 @@ private final Collection sharers = new HashSet(1); public static NotificationBuffer getNotificationBuffer( - MBeanServer mbs, Map env) { + MBeanServer mbs, Map env) { if (env == null) env = Collections.emptyMap(); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Fri Nov 21 15:10:14 2008 -0500 @@ -54,7 +54,7 @@ public abstract class ClientNotifForwarder { - public ClientNotifForwarder(Map env) { + public ClientNotifForwarder(Map env) { this(null, env); } @@ -113,7 +113,7 @@ private Thread thread; } - public ClientNotifForwarder(ClassLoader defaultClassLoader, Map env) { + public ClientNotifForwarder(ClassLoader defaultClassLoader, Map env) { maxNotifications = EnvHelp.getMaxFetchNotifNumber(env); timeout = EnvHelp.getFetchTimeout(env); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java Fri Nov 21 15:10:14 2008 -0500 @@ -36,7 +36,7 @@ import org.omg.CORBA.TypeCode; import org.omg.CORBA.portable.BoxedValueHelper; -@SuppressWarnings("deprecation") +@SuppressWarnings({"deprecation", "rawtypes"}) public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream { public ProxyInputStream(org.omg.CORBA.portable.InputStream in) { this.in = in; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java Fri Nov 21 15:10:14 2008 -0500 @@ -59,7 +59,7 @@ public ServerNotifForwarder(MBeanServer mbeanServer, - Map env, + Map env, NotificationBuffer notifBuffer, String connectionId) { this.mbeanServer = mbeanServer; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java Fri Nov 21 15:10:14 2008 -0500 @@ -29,6 +29,6 @@ import java.rmi.MarshalledObject; public interface Unmarshal { - public Object get(MarshalledObject mo) + public Object get(MarshalledObject mo) throws IOException, ClassNotFoundException; } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java --- a/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Fri Nov 21 15:10:14 2008 -0500 @@ -26,6 +26,7 @@ package com.sun.jmx.remote.security; import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.mbeanserver.Util; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -146,8 +147,8 @@ // Initial state private Subject subject; private CallbackHandler callbackHandler; - private Map sharedState; - private Map options; + private Map sharedState; + private Map options; private String passwordFile; private String passwordFileDisplayName; private boolean userSuppliedPasswordFile; @@ -172,7 +173,7 @@ this.subject = subject; this.callbackHandler = callbackHandler; - this.sharedState = sharedState; + this.sharedState = Util.cast(sharedState); this.options = options; // initialize any configured options @@ -454,8 +455,8 @@ if (storePass && !sharedState.containsKey(USERNAME_KEY) && !sharedState.containsKey(PASSWORD_KEY)) { - ((Map) sharedState).put(USERNAME_KEY, username); - ((Map) sharedState).put(PASSWORD_KEY, password); + sharedState.put(USERNAME_KEY, username); + sharedState.put(PASSWORD_KEY, password); } // Create a new user principal diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java --- a/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java Fri Nov 21 15:10:14 2008 -0500 @@ -87,7 +87,7 @@ * @exception SecurityException if the authentication mechanism cannot be * initialized. */ - public JMXPluggableAuthenticator(Map env) { + public JMXPluggableAuthenticator(Map env) { String loginConfigName = null; String passwordFile = null; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java --- a/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java Fri Nov 21 15:10:14 2008 -0500 @@ -249,9 +249,8 @@ } }); if (s == null) return; /* security has not been enabled */ - final Set principals = s.getPrincipals(); - for (Iterator i = principals.iterator(); i.hasNext(); ) { - final Principal p = (Principal) i.next(); + final Set principals = s.getPrincipals(); + for (Principal p : principals) { String grantedAccessLevel; synchronized (props) { grantedAccessLevel = props.getProperty(p.getName()); @@ -271,8 +270,8 @@ } private void checkValues(Properties props) { - Collection c = props.values(); - for (Iterator i = c.iterator(); i.hasNext(); ) { + Collection c = props.values(); + for (Iterator i = c.iterator(); i.hasNext(); ) { final String accessLevel = (String) i.next(); if (!accessLevel.equals(READONLY) && !accessLevel.equals(READWRITE)) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java --- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Fri Nov 21 15:10:14 2008 -0500 @@ -38,7 +38,7 @@ this.cl2 = cl2; } - protected Class findClass(String name) throws ClassNotFoundException { + protected Class findClass(String name) throws ClassNotFoundException { try { return repository.loadClass(name); } catch (ClassNotFoundException cne) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java --- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java Fri Nov 21 15:10:14 2008 -0500 @@ -41,7 +41,7 @@ people to use at least J2SE 1.4. */ boolean loaded = false; try { - Class c = java.util.logging.Logger.class; + Class c = java.util.logging.Logger.class; loaded = true; } catch (Error e) { // OK. diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java --- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Fri Nov 21 15:10:14 2008 -0500 @@ -117,7 +117,7 @@ * jmx.remote.default.class.loader.name is specified * and the ClassLoader MBean is not found in mbs. */ - public static ClassLoader resolveServerClassLoader(Map env, + public static ClassLoader resolveServerClassLoader(Map env, MBeanServer mbs) throws InstanceNotFoundException { @@ -194,7 +194,7 @@ * jmx.remote.default.class.loader is specified * and is not an instance of {@link ClassLoader}. */ - public static ClassLoader resolveClientClassLoader(Map env) { + public static ClassLoader resolveClientClassLoader(Map env) { if (env == null) return Thread.currentThread().getContextClassLoader(); @@ -241,7 +241,7 @@ try { java.lang.reflect.Method getCause = - t.getClass().getMethod("getCause", (Class[]) null); + t.getClass().getMethod("getCause", (Class[]) null); ret = (Throwable)getCause.invoke(t, (Object[]) null); } catch (Exception e) { @@ -264,7 +264,7 @@ * Returns the size of a notification buffer for a connector server. * The default value is 1000. */ - public static int getNotifBufferSize(Map env) { + public static int getNotifBufferSize(Map env) { int defaultQueueSize = 1000; // default value // keep it for the compability for the fix: @@ -327,7 +327,7 @@ * Returns the maximum notification number which a client will * fetch every time. */ - public static int getMaxFetchNotifNumber(Map env) { + public static int getMaxFetchNotifNumber(Map env) { return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1, Integer.MAX_VALUE); } @@ -344,7 +344,7 @@ /** * Returns the timeout for a client to fetch notifications. */ - public static long getFetchTimeout(Map env) { + public static long getFetchTimeout(Map env) { return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0, Long.MAX_VALUE); } @@ -361,7 +361,7 @@ "com.sun.jmx.remote.notification.access.controller"; public static NotificationAccessController getNotificationAccessController( - Map env) { + Map env) { return (env == null) ? null : (NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER); } @@ -378,7 +378,7 @@ * an entry for name but it does not meet the * constraints above. */ - public static long getIntegerAttribute(Map env, String name, + public static long getIntegerAttribute(Map env, String name, long defaultValue, long minValue, long maxValue) { final Object o; @@ -421,9 +421,8 @@ /* Check that all attributes have a key that is a String. Could make further checks, e.g. appropriate types for attributes. */ - public static void checkAttributes(Map attributes) { - for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ) { - Object key = it.next(); + public static void checkAttributes(Map attributes) { + for (Object key : attributes.keySet()) { if (!(key instanceof String)) { final String msg = "Attributes contain key that is not a string: " + key; @@ -455,7 +454,7 @@ logger.trace("purgeUnserializable", "starts"); ObjectOutputStream oos = null; int i = 0; - for (Iterator it = objects.iterator(); it.hasNext(); i++) { + for (Iterator it = objects.iterator(); it.hasNext(); i++) { Object v = it.next(); if (v == null || v instanceof String) { @@ -564,18 +563,18 @@ guarantees that we will never call next() on the corresponding iterator. */ String sentinelKey = map.lastKey() + "X"; - Iterator keyIterator = map.keySet().iterator(); - Iterator stringIterator = hiddenStrings.iterator(); - Iterator prefixIterator = hiddenPrefixes.iterator(); + Iterator keyIterator = map.keySet().iterator(); + Iterator stringIterator = hiddenStrings.iterator(); + Iterator prefixIterator = hiddenPrefixes.iterator(); String nextString; if (stringIterator.hasNext()) - nextString = (String) stringIterator.next(); + nextString = stringIterator.next(); else nextString = sentinelKey; String nextPrefix; if (prefixIterator.hasNext()) - nextPrefix = (String) prefixIterator.next(); + nextPrefix = prefixIterator.next(); else nextPrefix = sentinelKey; @@ -583,7 +582,7 @@ or prefix, remove it. */ keys: while (keyIterator.hasNext()) { - String key = (String) keyIterator.next(); + String key = keyIterator.next(); /* Continue through string-match values until we find one that is either greater than the current key, or equal @@ -591,7 +590,7 @@ int cmp = +1; while ((cmp = nextString.compareTo(key)) < 0) { if (stringIterator.hasNext()) - nextString = (String) stringIterator.next(); + nextString = stringIterator.next(); else nextString = sentinelKey; } @@ -609,7 +608,7 @@ continue keys; } if (prefixIterator.hasNext()) - nextPrefix = (String) prefixIterator.next(); + nextPrefix = prefixIterator.next(); else nextPrefix = sentinelKey; } @@ -640,7 +639,7 @@ /** * Returns the server side connection timeout. */ - public static long getServerConnectionTimeout(Map env) { + public static long getServerConnectionTimeout(Map env) { return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L, 0, Long.MAX_VALUE); } @@ -656,7 +655,7 @@ /** * Returns the client connection check period. */ - public static long getConnectionCheckPeriod(Map env) { + public static long getConnectionCheckPeriod(Map env) { return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L, 0, Long.MAX_VALUE); } @@ -691,7 +690,7 @@ * to {@code String}. */ public static boolean computeBooleanFromString( - Map env, String prop, boolean systemProperty) { + Map env, String prop, boolean systemProperty) { if (env == null) throw new IllegalArgumentException("env map cannot be null"); @@ -744,7 +743,8 @@ * to {@code String}. */ public static boolean computeBooleanFromString( - Map env, String prop, boolean systemProperty, boolean defaultValue) { + Map env, String prop, + boolean systemProperty, boolean defaultValue) { if (env == null) throw new IllegalArgumentException("env map cannot be null"); @@ -774,7 +774,7 @@ public static Hashtable mapToHashtable(Map map) { HashMap m = new HashMap(map); if (m.containsKey(null)) m.remove(null); - for (Iterator i = m.values().iterator(); i.hasNext(); ) + for (Iterator i = m.values().iterator(); i.hasNext(); ) if (i.next() == null) i.remove(); return new Hashtable(m); } @@ -783,7 +783,7 @@ * Returns true if the parameter JMXConnector.USE_EVENT_SERVICE is set to a * String equals "true" by ignoring case in the map or in the System. */ - public static boolean eventServiceEnabled(Map env) { + public static boolean eventServiceEnabled(Map env) { return computeBooleanFromString(env, JMXConnector.USE_EVENT_SERVICE, true); } @@ -793,7 +793,7 @@ * If the property DELEGATE_TO_EVENT_SERVICE is not set, returns * a default value of "true". */ - public static boolean delegateToEventService(Map env) { + public static boolean delegateToEventService(Map env) { return computeBooleanFromString(env, JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java --- a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java Fri Nov 21 15:10:14 2008 -0500 @@ -138,8 +138,8 @@ Class interfaceClass, Callable eventClientFactory) { final InvocationHandler handler = new EventClientConnection(connection,eventClientFactory); - final Class[] interfaces = - new Class[] {interfaceClass, EventClientFactory.class}; + final Class[] interfaces = + new Class[] {interfaceClass, EventClientFactory.class}; Object proxy = Proxy.newProxyInstance(interfaceClass.getClassLoader(), @@ -156,7 +156,7 @@ // add/remove notification listener are routed to the EventClient if (methodName.equals("addNotificationListener") || methodName.equals("removeNotificationListener")) { - final Class[] sig = method.getParameterTypes(); + final Class[] sig = method.getParameterTypes(); if (sig.length>1 && NotificationListener.class.isAssignableFrom(sig[1])) { return invokeBroadcasterMethod(proxy,method,args); @@ -164,7 +164,7 @@ } // subscribe/unsubscribe are also routed to the EventClient. - final Class clazz = method.getDeclaringClass(); + final Class clazz = method.getDeclaringClass(); if (clazz.equals(EventClientFactory.class)) { return invokeEventClientSubscriberMethod(proxy,method,args); } @@ -319,7 +319,7 @@ return true; if (methodName.equals("equals") && Arrays.equals(method.getParameterTypes(), - new Class[] {Object.class}) + new Class[] {Object.class}) && isLocal(proxy, method)) return true; return false; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java --- a/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java Fri Nov 21 15:10:14 2008 -0500 @@ -32,7 +32,7 @@ this.cl2 = cl2; } - protected Class findClass(String name) throws ClassNotFoundException { + protected Class findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException cne) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java Fri Nov 21 15:10:14 2008 -0500 @@ -70,10 +70,13 @@ */ public static void registerElementById(Element element, String idValue) { Document doc = element.getOwnerDocument(); - WeakHashMap elementMap = (WeakHashMap) docMap.get(doc); - if(elementMap == null) { - elementMap = new WeakHashMap(); - docMap.put(doc, elementMap); + WeakHashMap elementMap; + synchronized (docMap) { + elementMap = (WeakHashMap) docMap.get(doc); + if (elementMap == null) { + elementMap = new WeakHashMap(); + docMap.put(doc, elementMap); + } } elementMap.put(idValue, new WeakReference(element)); } @@ -153,7 +156,10 @@ private static Element getElementByIdType(Document doc, String id) { if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "getElementByIdType() Search for ID " + id); - WeakHashMap elementMap = (WeakHashMap) docMap.get(doc); + WeakHashMap elementMap; + synchronized (docMap) { + elementMap = (WeakHashMap) docMap.get(doc); + } if (elementMap != null) { WeakReference weakReference = (WeakReference) elementMap.get(id); if (weakReference != null) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/AttributeList.java --- a/jdk/src/share/classes/javax/management/AttributeList.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/AttributeList.java Fri Nov 21 15:10:14 2008 -0500 @@ -159,7 +159,7 @@ checkTypeSafe(this); typeSafe = true; } - return (List) (List) this; + return (List) (List) this; } /** diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/DefaultLoaderRepository.java --- a/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java Fri Nov 21 15:10:14 2008 -0500 @@ -62,7 +62,7 @@ * * @exception ClassNotFoundException The specified class could not be found. */ - public static Class loadClass(String className) + public static Class loadClass(String className) throws ClassNotFoundException { return javax.management.loading.DefaultLoaderRepository.loadClass(className); } @@ -82,7 +82,7 @@ * * @exception ClassNotFoundException The specified class could not be found. */ - public static Class loadClassWithout(ClassLoader loader,String className) + public static Class loadClassWithout(ClassLoader loader,String className) throws ClassNotFoundException { return javax.management.loading.DefaultLoaderRepository.loadClassWithout(loader, className); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/Descriptor.java --- a/jdk/src/share/classes/javax/management/Descriptor.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/Descriptor.java Fri Nov 21 15:10:14 2008 -0500 @@ -101,7 +101,7 @@ * * NameTypeUsed inMeaning * - * defaultValueObject + * defaultValueObject * MBeanAttributeInfo
MBeanParameterInfo * * Default value for an attribute or parameter. See @@ -144,7 +144,7 @@ * might be disabled if it cannot currently be emitted but could be in * other circumstances. * - * immutableInfoString + * immutableInfoString * MBeanInfo * * The string {@code "true"} or {@code "false"} according as this @@ -153,20 +153,24 @@ * the lifetime of the MBean. Hence, a client can read it once and * cache the read value. When this field is false or absent, there is * no such guarantee, although that does not mean that the MBeanInfo - * will necessarily change. + * will necessarily change. See also the {@code "jmx.mbean.info.changed"} + * notification. * * infoTimeoutString
LongMBeanInfo * - * The time in milli-seconds that the MBeanInfo can reasonably be - * expected to be unchanged. The value can be a {@code Long} or a - * decimal string. This provides a hint from a DynamicMBean or any + * The time in milli-seconds that the MBeanInfo can + * reasonably be expected to be unchanged. The value can be a {@code Long} + * or a decimal string. This provides a hint from a DynamicMBean or any * MBean that does not define {@code immutableInfo} as {@code true} * that the MBeanInfo is not likely to change within this period and * therefore can be cached. When this field is missing or has the * value zero, it is not recommended to cache the MBeanInfo unless it - * has the {@code immutableInfo} set to {@code true}. + * has the {@code immutableInfo} set to {@code true} or it has {@code "jmx.mbean.info.changed"} in + * its {@link MBeanNotificationInfo} array. * - * interfaceClassName + * interfaceClassName * StringMBeanInfo * * The Java interface name for a Standard MBean or MXBean, as @@ -175,19 +179,19 @@ * StandardMBean} class will have this field in its MBeanInfo * Descriptor. * - * legalValues + * legalValues * {@literal Set}MBeanAttributeInfo
MBeanParameterInfo * * Legal values for an attribute or parameter. See * {@link javax.management.openmbean}. * - * maxValueObject + * maxValueObject * MBeanAttributeInfo
MBeanParameterInfo * * Maximum legal value for an attribute or parameter. See * {@link javax.management.openmbean}. * - * metricTypeString + * metricTypeString * MBeanAttributeInfo
MBeanOperationInfo * * The type of a metric, one of the strings "counter" or "gauge". @@ -200,13 +204,13 @@ * that can increase or decrease. Examples might be the number of * open connections or a cache hit rate or a temperature reading. * - * minValueObject + * minValueObject * MBeanAttributeInfo
MBeanParameterInfo * * Minimum legal value for an attribute or parameter. See * {@link javax.management.openmbean}. * - * mxbeanString + * mxbeanString * MBeanInfo * * The string {@code "true"} or {@code "false"} according as this @@ -223,7 +227,7 @@ * MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default} * one. * - * openType{@link OpenType} + * openType{@link OpenType} * MBeanAttributeInfo
MBeanOperationInfo
MBeanParameterInfo * *

The Open Type of this element. In the case of {@code @@ -240,7 +244,7 @@ * which case it indicates the Open Type that the {@link * Notification#getUserData() user data} will have. * - * originalTypeString + * originalTypeString * MBeanAttributeInfo
MBeanOperationInfo
MBeanParameterInfo * *

The original Java type of this element as it appeared in the @@ -282,11 +286,132 @@ * * * - *

Some additional fields are defined by Model MBeans. See - * {@link javax.management.modelmbean.ModelMBeanInfo ModelMBeanInfo} - * and related classes and the chapter "Model MBeans" of the - * - * JMX Specification.

+ *

Some additional fields are defined by Model MBeans. See the + * information for {@code ModelMBeanInfo}, + * {@code ModelMBeanAttributeInfo}, + * {@code ModelMBeanConstructorInfo}, + * {@code ModelMBeanNotificationInfo}, and + * {@code ModelMBeanOperationInfo}, as + * well as the chapter "Model MBeans" of the JMX + * Specification. The following table summarizes these fields. Note + * that when the Type in this table is Number, a String that is the decimal + * representation of a Long can also be used.

+ * + *

Nothing prevents the use of these fields in MBeans that are not Model + * MBeans. The displayName, severity, and visibility fields are of + * interest outside Model MBeans, for example. But only Model MBeans have + * a predefined behavior for these fields.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameTypeUsed inMeaning
classStringModelMBeanOperationInfoClass where method is defined (fully qualified).
currencyTimeLimitNumberModelMBeanInfo
ModelMBeanAttributeInfo
ModelMBeanOperationInfo
How long cached value is valid: <0 never, =0 always, + * >0 seconds.
defaultObjectModelMBeanAttributeInfoDefault value for attribute.
descriptorTypeStringAnyType of descriptor, "mbean", "attribute", "constructor", "operation", + * or "notification".
displayNameStringAnyHuman readable name of this item.
exportStringModelMBeanInfoName to be used to export/expose this MBean so that it is + * findable by other JMX Agents.
getMethodStringModelMBeanAttributeInfoName of operation descriptor for get method.
lastUpdatedTimeStampNumberModelMBeanAttributeInfo
ModelMBeanOperationInfo
When value was set.
logStringModelMBeanInfo
ModelMBeanNotificationInfo
t or T: log all notifications, f or F: log no notifications.
logFileStringModelMBeanInfo
ModelMBeanNotificationInfo
Fully qualified filename to log events to.
messageIDStringModelMBeanNotificationInfoUnique key for message text (to allow translation, analysis).
messageTextStringModelMBeanNotificationInfoText of notification.
nameStringAnyName of this item.
persistFileStringModelMBeanInfoFile name into which the MBean should be persisted.
persistLocationStringModelMBeanInfoThe fully qualified directory name where the MBean should be + * persisted (if appropriate).
persistPeriodNumberModelMBeanInfo
ModelMBeanAttributeInfo
Frequency of persist cycle in seconds. Used when persistPolicy is + * "OnTimer" or "NoMoreOftenThan".
persistPolicyStringModelMBeanInfo
ModelMBeanAttributeInfo
One of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never. + * See the section "MBean Descriptor Fields" in the JMX specification + * document.
presentationStringStringAnyXML formatted string to allow presentation of data.
protocolMapDescriptorModelMBeanAttributeInfoSee the section "Protocol Map Support" in the JMX specification + * document. Mappings must be appropriate for the attribute and entries + * can be updated or augmented at runtime.
roleStringModelMBeanConstructorInfo
ModelMBeanOperationInfo
One of "constructor", "operation", "getter", or "setter".
setMethodStringModelMBeanAttributeInfoName of operation descriptor for set method.
severityNumberModelMBeanNotificationInfo0-6 where 0: unknown; 1: non-recoverable; + * 2: critical, failure; 3: major, severe; + * 4: minor, marginal, error; 5: warning; + * 6: normal, cleared, informative
targetObjectObjectModelMBeanOperationInfoObject on which to execute this method.
targetTypeStringModelMBeanOperationInfotype of object reference for targetObject. Can be: + * ObjectReference | Handle | EJBHandle | IOR | RMIReference.
valueObjectModelMBeanAttributeInfo
ModelMBeanOperationInfo
Current (cached) value for attribute or operation.
visibilityNumberAny1-4 where 1: always visible, 4: rarely visible.
* * @since 1.5 */ @@ -439,7 +564,7 @@ public boolean isValid() throws RuntimeOperationsException; /** - * Compares this descriptor to the given object. The objects are equal if + *

Compares this descriptor to the given object. The objects are equal if * the given object is also a Descriptor, and if the two Descriptors have * the same field names (possibly differing in case) and the same * associated values. The respective values for a field in the two diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/JMRuntimeException.java --- a/jdk/src/share/classes/javax/management/JMRuntimeException.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/JMRuntimeException.java Fri Nov 21 15:10:14 2008 -0500 @@ -70,7 +70,7 @@ try { java.lang.reflect.Method initCause = Throwable.class.getMethod("initCause", - new Class[] {Throwable.class}); + new Class[] {Throwable.class}); initCause.invoke(this, new Object[] {cause}); } catch (Exception e) { // OK: just means we won't have debugging info diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/JMX.java --- a/jdk/src/share/classes/javax/management/JMX.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/JMX.java Fri Nov 21 15:10:14 2008 -0500 @@ -463,6 +463,12 @@ * likewise for the other methods of {@link * NotificationBroadcaster} and {@link NotificationEmitter}.

* + *

This method is equivalent to {@link + * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions) + * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where + * {@code opts} is a {@link JMX.ProxyOptions} representing the + * {@code notificationEmitter} parameter.

+ * * @param connection the MBean server to forward to. * @param objectName the name of the MBean within * {@code connection} to forward to. @@ -555,10 +561,6 @@ * * * - *

The object returned by this method is a - * {@link Proxy} whose {@code InvocationHandler} is an - * {@link MBeanServerInvocationHandler}.

- * *

This method is equivalent to {@link * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class, * boolean) newMXBeanProxy(connection, objectName, interfaceClass, @@ -601,6 +603,17 @@ * likewise for the other methods of {@link * NotificationBroadcaster} and {@link NotificationEmitter}.

* + *

This method is equivalent to {@link + * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions) + * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where + * {@code opts} is a {@link JMX.ProxyOptions} where the {@link + * JMX.ProxyOptions#getMXBeanMappingFactory() MXBeanMappingFactory} + * property is + * {@link MXBeanMappingFactory#forInterface(Class) + * MXBeanMappingFactory.forInterface(interfaceClass)} and the {@link + * JMX.ProxyOptions#isNotificationEmitter() notificationEmitter} property + * is equal to the {@code notificationEmitter} parameter.

+ * * @param connection the MBean server to forward to. * @param objectName the name of the MBean within * {@code connection} to forward to. @@ -655,6 +668,36 @@ * arbitrary Java types and Open Types. * * + *

The object returned by this method is a + * {@link Proxy} whose {@code InvocationHandler} is an + * {@link MBeanServerInvocationHandler}. This means that it is possible + * to retrieve the parameters that were used to produce the proxy. If the + * proxy was produced as follows...

+ * + *
+     * FooMBean proxy =
+     *     JMX.newMBeanProxy(connection, objectName, FooMBean.class, opts);
+     * 
+ * + *

...then you can get the {@code MBeanServerInvocationHandler} like + * this...

+ * + *
+     * MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
+     *     {@link Proxy#getInvocationHandler(Object)
+     *            Proxy.getInvocationHandler}(proxy);
+     * 
+ * + *

...and you can retrieve {@code connection}, {@code + * objectName}, and {@code opts} using the {@link + * MBeanServerInvocationHandler#getMBeanServerConnection() + * getMBeanServerConnection()}, {@link + * MBeanServerInvocationHandler#getObjectName() getObjectName()}, and + * {@link MBeanServerInvocationHandler#getMBeanOptions() getMBeanOptions()} + * methods on {@code mbsih}. You can retrieve {@code FooMBean.class} + * using {@code proxy.getClass().}{@link + * Class#getInterfaces() getInterfaces()}.

+ * * @param connection the MBean server to forward to. * @param objectName the name of the MBean within * {@code connection} to forward to. @@ -703,12 +746,12 @@ InvocationHandler handler = new MBeanServerInvocationHandler( connection, objectName, opts); - final Class[] interfaces; + final Class[] interfaces; if (notificationEmitter) { interfaces = new Class[] {interfaceClass, NotificationEmitter.class}; } else - interfaces = new Class[] {interfaceClass}; + interfaces = new Class[] {interfaceClass}; Object proxy = Proxy.newProxyInstance( interfaceClass.getClassLoader(), interfaces, diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanAttributeInfo.java --- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -316,7 +316,7 @@ */ private static String attributeType(Method getter, Method setter) throws IntrospectionException { - Class type = null; + Class type = null; if (getter != null) { if (getter.getParameterTypes().length != 0) { @@ -330,7 +330,7 @@ } if (setter != null) { - Class params[] = setter.getParameterTypes(); + Class params[] = setter.getParameterTypes(); if (params.length != 1) { throw new IntrospectionException("bad setter arg count"); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanConstructorInfo.java --- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -64,7 +64,7 @@ * @param constructor The java.lang.reflect.Constructor * object describing the MBean constructor. */ - public MBeanConstructorInfo(String description, Constructor constructor) { + public MBeanConstructorInfo(String description, Constructor constructor) { this(constructor.getName(), description, constructorSignature(constructor), Introspector.descriptorForElement(constructor)); @@ -210,8 +210,8 @@ return hash; } - private static MBeanParameterInfo[] constructorSignature(Constructor cn) { - final Class[] classes = cn.getParameterTypes(); + private static MBeanParameterInfo[] constructorSignature(Constructor cn) { + final Class[] classes = cn.getParameterTypes(); final Annotation[][] annots = cn.getParameterAnnotations(); return MBeanOperationInfo.parameters(classes, annots); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanInfo.java --- a/jdk/src/share/classes/javax/management/MBeanInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -45,6 +45,17 @@ * management operations. Instances of this class are immutable. * Subclasses may be mutable but this is not recommended.

* + *

Usually the {@code MBeanInfo} for any given MBean does + * not change over the lifetime of that MBean. Dynamic MBeans can change their + * {@code MBeanInfo} and in that case it is recommended that they emit a {@link + * Notification} with a {@linkplain Notification#getType() type} of {@code + * "jmx.mbean.info.changed"} and a {@linkplain Notification#getUserData() + * userData} that is the new {@code MBeanInfo}. This is not required, but + * provides a conventional way for clients of the MBean to discover the change. + * See also the immutableInfo and + * infoTimeout fields in the {@code + * MBeanInfo} {@link Descriptor}.

+ * *

The contents of the MBeanInfo for a Dynamic MBean * are determined by its {@link DynamicMBean#getMBeanInfo * getMBeanInfo()} method. This includes Open MBeans and Model @@ -62,27 +73,49 @@ * constructors in that object; * *

  • {@link #getAttributes()} returns the list of all attributes - * whose existence is deduced from the presence in the MBean interface - * of a getName, isName, or - * setName method that conforms to the conventions + * whose existence is deduced as follows: + *
      + *
    • if the Standard MBean is defined with an MBean interface, + * from getName, isName, or + * setName methods that conform to the conventions * for Standard MBeans; + *
    • if the Standard MBean is defined with the {@link MBean @MBean} or + * {@link MXBean @MXBean} annotation on a class, from methods with the + * {@link ManagedAttribute @ManagedAttribute} annotation; + *
    * - *
  • {@link #getOperations()} returns the list of all methods in + *
  • {@link #getOperations()} returns the list of all operations whose + * existence is deduced as follows: + *
      + *
    • if the Standard MBean is defined with an MBean interface, from methods in * the MBean interface that do not represent attributes; + *
    • if the Standard MBean is defined with the {@link MBean @MBean} or + * {@link MXBean @MXBean} annotation on a class, from methods with the + * {@link ManagedOperation @ManagedOperation} annotation; + *
    * - *
  • {@link #getNotifications()} returns an empty array if the MBean - * does not implement the {@link NotificationBroadcaster} interface, - * otherwise the result of calling {@link + *
  • {@link #getNotifications()} returns: + *
      + *
    • if the MBean implements the {@link NotificationBroadcaster} interface, + * the result of calling {@link * NotificationBroadcaster#getNotificationInfo()} on it; + *
    • otherwise, if there is a {@link NotificationInfo @NotificationInfo} + * or {@link NotificationInfos @NotificationInfos} annotation on the + * MBean interface or @MBean or @MXBean + * class, the array implied by those annotations; + *
    • otherwise an empty array; + *
    * *
  • {@link #getDescriptor()} returns a descriptor containing the contents - * of any descriptor annotations in the MBean interface. + * of any descriptor annotations in the MBean interface (see + * {@link DescriptorFields @DescriptorFields} and + * {@link DescriptorKey @DescriptorKey}). * * * *

    The description returned by {@link #getDescription()} and the * descriptions of the contained attributes and operations are determined - * by the corresponding Description annotations if any; + * by the corresponding {@link Description} annotations if any; * otherwise their contents are not specified.

    * *

    The remaining details of the MBeanInfo for a @@ -524,8 +557,8 @@ * a WeakHashMap so that we don't prevent a class from being * garbage collected just because we know whether it's immutable. */ - private static final Map arrayGettersSafeMap = - new WeakHashMap(); + private static final Map, Boolean> arrayGettersSafeMap = + new WeakHashMap, Boolean>(); /** * Return true if subclass is known to preserve the @@ -537,7 +570,7 @@ * This is obviously not an infallible test for immutability, * but it works for the public interfaces of the MBean*Info classes. */ - static boolean arrayGettersSafe(Class subclass, Class immutableClass) { + static boolean arrayGettersSafe(Class subclass, Class immutableClass) { if (subclass == immutableClass) return true; synchronized (arrayGettersSafeMap) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanOperationInfo.java --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -308,17 +308,18 @@ wrong should be less than the penalty we would pay if it were right and we needlessly hashed in the description and the parameter array. */ + @Override public int hashCode() { return getName().hashCode() ^ getReturnType().hashCode(); } private static MBeanParameterInfo[] methodSignature(Method method) { - final Class[] classes = method.getParameterTypes(); + final Class[] classes = method.getParameterTypes(); final Annotation[][] annots = method.getParameterAnnotations(); return parameters(classes, annots); } - static MBeanParameterInfo[] parameters(Class[] classes, + static MBeanParameterInfo[] parameters(Class[] classes, Annotation[][] annots) { final MBeanParameterInfo[] params = new MBeanParameterInfo[classes.length]; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanServer.java --- a/jdk/src/share/classes/javax/management/MBeanServer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanServer.java Fri Nov 21 15:10:14 2008 -0500 @@ -377,19 +377,19 @@ * MBean will not be registered. * @exception RuntimeMBeanException If the postRegister * (MBeanRegistration interface) method of the MBean throws a - * RuntimeException, the registerMBean method will + * RuntimeException, the registerMBean method will * throw a RuntimeMBeanException, although the MBean * registration succeeded. In such a case, the MBean will be actually - * registered even though the registerMBean method + * registered even though the registerMBean method * threw an exception. Note that RuntimeMBeanException can * also be thrown by preRegister, in which case the MBean * will not be registered. * @exception RuntimeErrorException If the postRegister * (MBeanRegistration interface) method of the MBean throws an - * Error, the registerMBean method will + * Error, the registerMBean method will * throw a RuntimeErrorException, although the MBean * registration succeeded. In such a case, the MBean will be actually - * registered even though the registerMBean method + * registered even though the registerMBean method * threw an exception. Note that RuntimeErrorException can * also be thrown by preRegister, in which case the MBean * will not be registered. @@ -411,6 +411,8 @@ * is sent as described above.

    * * @throws RuntimeOperationsException {@inheritDoc} + * @throws RuntimeMBeanException {@inheritDoc} + * @throws RuntimeErrorException {@inheritDoc} */ public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanServerConnection.java --- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java Fri Nov 21 15:10:14 2008 -0500 @@ -76,7 +76,9 @@ * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. - * @exception RuntimeMBeanException If the postRegister + * @exception RuntimeMBeanException If the MBean's constructor or its + * {@code preRegister} or {@code postRegister} method threw + * a {@code RuntimeException}. If the postRegister * (MBeanRegistration interface) method of the MBean throws a * RuntimeException, the createMBean method will * throw a RuntimeMBeanException, although the MBean creation @@ -148,7 +150,9 @@ * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. - * @exception RuntimeMBeanException If the postRegister + * @exception RuntimeMBeanException If the MBean's constructor or its + * {@code preRegister} or {@code postRegister} method threw + * a {@code RuntimeException}. If the postRegister * (MBeanRegistration interface) method of the MBean throws a * RuntimeException, the createMBean method will * throw a RuntimeMBeanException, although the MBean creation @@ -223,7 +227,9 @@ * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. - * @exception RuntimeMBeanException If the postRegister + * @exception RuntimeMBeanException If the MBean's constructor or its + * {@code preRegister} or {@code postRegister} method threw + * a {@code RuntimeException}. If the postRegister * (MBeanRegistration interface) method of the MBean throws a * RuntimeException, the createMBean method will * throw a RuntimeMBeanException, although the MBean creation @@ -295,7 +301,9 @@ * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. - * @exception RuntimeMBeanException If the postRegister + * @exception RuntimeMBeanException The MBean's constructor or its + * {@code preRegister} or {@code postRegister} method threw + * a {@code RuntimeException}. If the postRegister * (MBeanRegistration interface) method of the MBean throws a * RuntimeException, the createMBean method will * throw a RuntimeMBeanException, although the MBean creation diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanServerFactory.java --- a/jdk/src/share/classes/javax/management/MBeanServerFactory.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanServerFactory.java Fri Nov 21 15:10:14 2008 -0500 @@ -747,7 +747,7 @@ * Load the builder class through the context class loader. * @param builderClassName The name of the builder class. **/ - private static Class loadBuilderClass(String builderClassName) + private static Class loadBuilderClass(String builderClassName) throws ClassNotFoundException { final ClassLoader loader = Thread.currentThread().getContextClassLoader(); @@ -767,7 +767,7 @@ * If any checked exception needs to be thrown, it is embedded in * a JMRuntimeException. **/ - private static MBeanServerBuilder newBuilder(Class builderClass) { + private static MBeanServerBuilder newBuilder(Class builderClass) { try { final Object abuilder = builderClass.newInstance(); return (MBeanServerBuilder)abuilder; @@ -792,7 +792,7 @@ String builderClassName = AccessController.doPrivileged(act); try { - final Class newBuilderClass; + final Class newBuilderClass; if (builderClassName == null || builderClassName.length() == 0) newBuilderClass = MBeanServerBuilder.class; else @@ -800,7 +800,7 @@ // Check whether a new builder needs to be created if (builder != null) { - final Class builderClass = builder.getClass(); + final Class builderClass = builder.getClass(); if (newBuilderClass == builderClass) return; // no need to create a new builder... } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java --- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java Fri Nov 21 15:10:14 2008 -0500 @@ -253,12 +253,12 @@ boolean notificationBroadcaster) { final InvocationHandler handler = new MBeanServerInvocationHandler(connection, objectName); - final Class[] interfaces; + final Class[] interfaces; if (notificationBroadcaster) { interfaces = - new Class[] {interfaceClass, NotificationEmitter.class}; + new Class[] {interfaceClass, NotificationEmitter.class}; } else - interfaces = new Class[] {interfaceClass}; + interfaces = new Class[] {interfaceClass}; Object proxy = Proxy.newProxyInstance(interfaceClass.getClassLoader(), @@ -269,7 +269,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - final Class methodClass = method.getDeclaringClass(); + final Class methodClass = method.getDeclaringClass(); if (methodClass.equals(NotificationBroadcaster.class) || methodClass.equals(NotificationEmitter.class)) @@ -285,8 +285,8 @@ return p.invoke(connection, objectName, method, args); } else { final String methodName = method.getName(); - final Class[] paramTypes = method.getParameterTypes(); - final Class returnType = method.getReturnType(); + final Class[] paramTypes = method.getParameterTypes(); + final Class returnType = method.getReturnType(); /* Inexplicably, InvocationHandler specifies that args is null when the method takes no arguments rather than a @@ -361,7 +361,13 @@ if (p != null) return p; } - p = new MXBeanProxy(mxbeanInterface, mappingFactory); + try { + p = new MXBeanProxy(mxbeanInterface, mappingFactory); + } catch (IllegalArgumentException e) { + String msg = "Cannot make MXBean proxy for " + + mxbeanInterface.getName() + ": " + e.getMessage(); + throw new IllegalArgumentException(msg, e.getCause()); + } classToProxy.put(mxbeanInterface, new WeakReference(p)); return p; } @@ -452,7 +458,7 @@ return true; if (methodName.equals("equals") && Arrays.equals(method.getParameterTypes(), - new Class[] {Object.class}) + new Class[] {Object.class}) && isLocal(proxy, method)) return true; return false; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/NotificationListener.java --- a/jdk/src/share/classes/javax/management/NotificationListener.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/NotificationListener.java Fri Nov 21 15:10:14 2008 -0500 @@ -39,11 +39,10 @@ * blocking its notification broadcaster. * * @param notification The notification. - * @param handback An opaque object which helps the listener to associate information - * regarding the MBean emitter. This object is passed to the MBean during the - * addListener call and resent, without modification, to the listener. The MBean object - * should not use or modify the object. - * + * @param handback An opaque object which helps the listener to associate + * information regarding the MBean emitter. This object is passed to the + * addNotificationListener call and resent, without modification, to the + * listener. */ - public void handleNotification(Notification notification, Object handback) ; + public void handleNotification(Notification notification, Object handback); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/StandardMBean.java --- a/jdk/src/share/classes/javax/management/StandardMBean.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/StandardMBean.java Fri Nov 21 15:10:14 2008 -0500 @@ -689,7 +689,7 @@ getImplementationClass().getName()); } - MBeanSupport msupport = mbean; + MBeanSupport msupport = mbean; final MBeanInfo bi = msupport.getMBeanInfo(); final Object impl = msupport.getWrappedObject(); @@ -1391,8 +1391,8 @@ * garbage collected just because we know whether its MBeanInfo * is immutable. */ - private static final Map mbeanInfoSafeMap = - new WeakHashMap(); + private static final Map, Boolean> mbeanInfoSafeMap = + new WeakHashMap, Boolean>(); /** * Return true if {@code subclass} is known to preserve the immutability @@ -1438,9 +1438,9 @@ private static class MBeanInfoSafeAction implements PrivilegedAction { - private final Class subclass; + private final Class subclass; - MBeanInfoSafeAction(Class subclass) { + MBeanInfoSafeAction(Class subclass) { this.subclass = subclass; } @@ -1454,13 +1454,13 @@ // Check for "MBeanInfo getCachedMBeanInfo()" method. // if (overrides(subclass, StandardMBean.class, - "getCachedMBeanInfo", (Class[]) null)) + "getCachedMBeanInfo", (Class[]) null)) return false; // Check for "MBeanInfo getMBeanInfo()" method. // if (overrides(subclass, StandardMBean.class, - "getMBeanInfo", (Class[]) null)) + "getMBeanInfo", (Class[]) null)) return false; // Check for "MBeanNotificationInfo[] getNotificationInfo()" @@ -1473,7 +1473,7 @@ // if (StandardEmitterMBean.class.isAssignableFrom(subclass)) if (overrides(subclass, StandardEmitterMBean.class, - "getNotificationInfo", (Class[]) null)) + "getNotificationInfo", (Class[]) null)) return false; return true; } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/event/EventClient.java --- a/jdk/src/share/classes/javax/management/event/EventClient.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/event/EventClient.java Fri Nov 21 15:10:14 2008 -0500 @@ -117,12 +117,12 @@ public static final String NONFATAL = "jmx.event.service.nonfatal"; /** - *

    A notification string type used by an {@code EventClient} object to - * inform a listener added by {@code #addEventClientListener} that it - * has detected that notifications have been lost. The {@link - * Notification#getUserData() userData} of the notification is a Long which - * is an upper bound on the number of lost notifications that have just - * been detected.

    + *

    A notification string type used by an {@code EventClient} object + * to inform a listener added by {@link #addEventClientListener + * addEventClientListener} that it has detected that notifications have + * been lost. The {@link Notification#getUserData() userData} of the + * notification is a Long which is an upper bound on the number of lost + * notifications that have just been detected.

    * * @see #addEventClientListener */ @@ -577,8 +577,13 @@ } /** - * Returns the set of listeners that have been added through - * this {@code EventClient} and not subsequently removed. + *

    Returns the collection of listeners that have been added through + * this {@code EventClient} and not subsequently removed. The returned + * collection contains one entry for every listener added with + * {@link #addNotificationListener addNotificationListener} or + * {@link #subscribe subscribe} and not subsequently removed with + * {@link #removeNotificationListener removeNotificationListener} or + * {@link #unsubscribe unsubscribe}, respectively.

    * * @return A collection of listener information. Empty if there are no * current listeners or if this {@code EventClient} has been {@linkplain @@ -927,8 +932,10 @@ private final static MBeanNotificationInfo[] myInfo = new MBeanNotificationInfo[] { new MBeanNotificationInfo( - new String[] {FAILED, NOTIFS_LOST}, - Notification.class.getName(), "")}; + new String[] {FAILED, NONFATAL, NOTIFS_LOST}, + Notification.class.getName(), + "Notifications that can be sent to a listener added with " + + "EventClient.addEventClientListener")}; private final NotificationBroadcasterSupport broadcaster = new NotificationBroadcasterSupport(); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/event/EventClientDelegate.java --- a/jdk/src/share/classes/javax/management/event/EventClientDelegate.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/event/EventClientDelegate.java Fri Nov 21 15:10:14 2008 -0500 @@ -104,8 +104,8 @@ public static EventClientDelegate getEventClientDelegate(MBeanServer server) { EventClientDelegate delegate = null; synchronized(delegateMap) { - final WeakReference wrf = delegateMap.get(server); - delegate = (wrf == null) ? null : (EventClientDelegate)wrf.get(); + final WeakReference wrf = delegateMap.get(server); + delegate = (wrf == null) ? null : wrf.get(); if (delegate == null) { delegate = new EventClientDelegate(server); @@ -282,7 +282,7 @@ Constructor foundCons = null; if (sig == null) sig = new String[0]; - for (Constructor cons : c.getConstructors()) { + for (Constructor cons : c.getConstructors()) { Class[] types = cons.getParameterTypes(); String[] consSig = new String[types.length]; for (int i = 0; i < types.length; i++) diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/event/EventSubscriber.java --- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java Fri Nov 21 15:10:14 2008 -0500 @@ -350,8 +350,7 @@ static { QueryExp broadcasterExp; try { - final Method m = Query.class.getMethod("isInstanceOf", - new Class[] {String.class}); + final Method m = Query.class.getMethod("isInstanceOf", String.class); broadcasterExp = (QueryExp)m.invoke(Query.class, new Object[] {NotificationBroadcaster.class.getName()}); } catch (Exception e) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java --- a/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java Fri Nov 21 15:10:14 2008 -0500 @@ -69,7 +69,7 @@ * @exception ClassNotFoundException The specified class could not be * found. */ - public static Class loadClass(String className) + public static Class loadClass(String className) throws ClassNotFoundException { MBEANSERVER_LOGGER.logp(Level.FINEST, DefaultLoaderRepository.class.getName(), @@ -93,7 +93,7 @@ * @exception ClassNotFoundException The specified class could not be * found. */ - public static Class loadClassWithout(ClassLoader loader, + public static Class loadClassWithout(ClassLoader loader, String className) throws ClassNotFoundException { MBEANSERVER_LOGGER.logp(Level.FINEST, @@ -102,12 +102,11 @@ return load(loader, className); } - private static Class load(ClassLoader without, String className) + private static Class load(ClassLoader without, String className) throws ClassNotFoundException { - final List mbsList = MBeanServerFactory.findMBeanServer(null); + final List mbsList = MBeanServerFactory.findMBeanServer(null); - for (Iterator it = mbsList.iterator(); it.hasNext(); ) { - MBeanServer mbs = (MBeanServer) it.next(); + for (MBeanServer mbs : mbsList) { ClassLoaderRepository clr = mbs.getClassLoaderRepository(); try { return clr.loadClassWithout(without, className); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/loading/MLet.java --- a/jdk/src/share/classes/javax/management/loading/MLet.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/loading/MLet.java Fri Nov 21 15:10:14 2008 -0500 @@ -1291,7 +1291,7 @@ if (c != null) { try { Constructor cons = - c.getConstructor(new Class[] {String.class}); + c.getConstructor(String.class); Object[] oo = new Object[1]; oo[0]=param; return(cons.newInstance(oo)); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java --- a/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java Fri Nov 21 15:10:14 2008 -0500 @@ -55,30 +55,30 @@ this.loader = loader; } - private Class primitiveType(char c) { + private Class primitiveType(char c) { switch(c) { - case 66: /* 'B' */ + case 'B': return Byte.TYPE; - case 67: /* 'C' */ + case 'C': return Character.TYPE; - case 68: /* 'D' */ + case 'D': return Double.TYPE; - case 70: /* 'F' */ + case 'F': return Float.TYPE; - case 73: /* 'I' */ + case 'I': return Integer.TYPE; - case 74: /* 'J' */ + case 'J': return Long.TYPE; - case 83: /* 'S' */ + case 'S': return Short.TYPE; - case 90: /* 'Z' */ + case 'Z': return Boolean.TYPE; } return null; @@ -87,14 +87,15 @@ /** * Use the given ClassLoader rather than using the system class */ - protected Class resolveClass(ObjectStreamClass objectstreamclass) + @Override + protected Class resolveClass(ObjectStreamClass objectstreamclass) throws IOException, ClassNotFoundException { String s = objectstreamclass.getName(); if (s.startsWith("[")) { int i; for (i = 1; s.charAt(i) == '['; i++); - Class class1; + Class class1; if (s.charAt(i) == 'L') { class1 = loader.loadClass(s.substring(i + 1, s.length() - 1)); } else { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java --- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -589,7 +589,7 @@ int numberOfEntries = descriptorMap.size(); String[] responseFields = new String[numberOfEntries]; - Set returnedSet = descriptorMap.entrySet(); + Set> returnedSet = descriptorMap.entrySet(); int i = 0; @@ -598,8 +598,9 @@ DescriptorSupport.class.getName(), "getFields()", "Returning " + numberOfEntries + " fields"); } - for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) { - Map.Entry currElement = (Map.Entry) iter.next(); + for (Iterator> iter = returnedSet.iterator(); + iter.hasNext(); i++) { + Map.Entry currElement = iter.next(); if (currElement == null) { if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { @@ -642,7 +643,7 @@ int numberOfEntries = descriptorMap.size(); String[] responseFields = new String[numberOfEntries]; - Set returnedSet = descriptorMap.entrySet(); + Set> returnedSet = descriptorMap.entrySet(); int i = 0; @@ -653,8 +654,9 @@ "Returning " + numberOfEntries + " fields"); } - for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) { - Map.Entry currElement = (Map.Entry) iter.next(); + for (Iterator> iter = returnedSet.iterator(); + iter.hasNext(); i++) { + Map.Entry currElement = iter.next(); if (( currElement == null ) || (currElement.getKey() == null)) { if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { @@ -700,9 +702,8 @@ } if (fieldNames == null) { - for (Iterator iter = descriptorMap.values().iterator(); - iter.hasNext(); i++) - responseFields[i] = iter.next(); + for (Object value : descriptorMap.values()) + responseFields[i++] = value; } else { for (i=0; i < fieldNames.length; i++) { if ((fieldNames[i] == null) || (fieldNames[i].equals(""))) { @@ -883,9 +884,9 @@ * not a String with value "t", "f", "true", "false". These String * values must not be case sensitive. *
  • visibility fieldName, if defined, is null, or not a - * Numeric String or a not Numeric Value >= 1 and <= 4 + * Numeric String or a not Numeric Value >= 1 and <= 4 *
  • severity fieldName, if defined, is null, or not a Numeric - * String or not a Numeric Value >= 0 and <= 6
    + * String or not a Numeric Value >= 0 and <= 6
    *
  • persistPolicy fieldName, if defined, is null, or not one of * the following strings:
    * "OnUpdate", "OnTimer", "NoMoreOftenThan", "OnUnregister", "Always", @@ -904,7 +905,7 @@ } // verify that the descriptor is valid, by iterating over each field... - Set returnedSet = descriptorMap.entrySet(); + Set> returnedSet = descriptorMap.entrySet(); if (returnedSet == null) { // null descriptor, not valid if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) { @@ -925,9 +926,7 @@ // According to the descriptor type we validate the fields contained - for (Iterator iter = returnedSet.iterator(); iter.hasNext();) { - Map.Entry currElement = (Map.Entry) iter.next(); - + for (Map.Entry currElement : returnedSet) { if (currElement != null) { if (currElement.getValue() != null) { // validate the field valued... @@ -1083,10 +1082,9 @@ */ public synchronized String toXMLString() { final StringBuilder buf = new StringBuilder(""); - Set returnedSet = descriptorMap.entrySet(); - for (Iterator iter = returnedSet.iterator(); iter.hasNext(); ) { - final Map.Entry currElement = (Map.Entry) iter.next(); - final String name = currElement.getKey().toString(); + Set> returnedSet = descriptorMap.entrySet(); + for (Map.Entry currElement : returnedSet) { + final String name = currElement.getKey(); Object value = currElement.getValue(); String valueString = null; /* Set valueString to non-null if and only if this is a string that @@ -1256,7 +1254,7 @@ } final Class c = Class.forName(className, false, contextClassLoader); - constr = c.getConstructor(new Class[] {String.class}); + constr = c.getConstructor(new Class[] {String.class}); } catch (Exception e) { throw new XMLParseException(e, "Cannot parse value: <" + s + ">"); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanAttributeInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -39,7 +39,6 @@ import java.io.ObjectStreamField; import java.lang.reflect.Method; import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.logging.Level; import javax.management.Descriptor; @@ -49,32 +48,56 @@ import javax.management.RuntimeOperationsException; /** - * The ModelMBeanAttributeInfo object describes an attribute of the ModelMBean. + *

    The ModelMBeanAttributeInfo object describes an attribute of the ModelMBean. * It is a subclass of MBeanAttributeInfo with the addition of an associated Descriptor - * and an implementation of the DescriptorAccess interface. - *

    - * The fields in the descriptor are defined, but not limited to, the following:

    - *

    - * name           : attribute name
    - * descriptorType : must be "attribute"
    - * value          : current value for attribute
    - * default        : default value for attribute
    - * displayName    : name of attribute to be used in displays
    - * getMethod      : name of operation descriptor for get method
    - * setMethod      : name of operation descriptor for set method
    - * protocolMap    : object which implements the Descriptor interface: mappings
    - *                  must be appropriate for the attribute
    - *                  and entries can be updated or augmented at runtime.
    - * persistPolicy  : OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never
    - * persistPeriod  : seconds - frequency of persist cycle. Used when persistPolicy
    - *                  is "OnTimer" or "NoMoreOftenThan".
    - * currencyTimeLimit : how long value is valid, <0 never, =0 always, >0 seconds
    - * lastUpdatedTimeStamp : when value was set
    - * visibility     : 1-4 where 1: always visible, 4: rarely visible
    - * presentationString : xml formatted string to allow presentation of data
    - * 
    - * The default descriptor contains the name, descriptorType and displayName fields. - * The default value of the name and displayName fields is the name of the attribute. + * and an implementation of the DescriptorAccess interface.

    + * + *

    + * The fields in the descriptor are defined, but not limited to, the following. + * Note that when the Type in this table is Number, a String that is the decimal + * representation of a Long can also be used.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NameTypeMeaning
    nameStringAttribute name.
    descriptorTypeStringMust be "attribute".
    valueObjectCurrent (cached) value for attribute.
    defaultObjectDefault value for attribute.
    displayNameStringName of attribute to be used in displays.
    getMethodStringName of operation descriptor for get method.
    setMethodStringName of operation descriptor for set method.
    protocolMapDescriptorSee the section "Protocol Map Support" in the JMX specification + * document. Mappings must be appropriate for the attribute and entries + * can be updated or augmented at runtime.
    persistPolicyStringOne of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never. + * See the section "MBean Descriptor Fields" in the JMX specification + * document.
    persistPeriodNumberFrequency of persist cycle in seconds. Used when persistPolicy is + * "OnTimer" or "NoMoreOftenThan".
    currencyTimeLimitNumberHow long value is valid: <0 never, + * =0 always, >0 seconds.
    lastUpdatedTimeStampNumberWhen value was set.
    visibilityNumber1-4 where 1: always visible, 4: rarely visible.
    presentationStringStringXML formatted string to allow presentation of data.
    + * + *

    The default descriptor contains the name, descriptorType and displayName + * fields. The default value of the name and displayName fields is the name of + * the attribute.

    * *

    Note: because of inconsistencies in previous versions of * this specification, it is recommended not to use negative or zero diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanConstructorInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -49,22 +49,33 @@ import javax.management.RuntimeOperationsException; /** - * The ModelMBeanConstructorInfo object describes a constructor of the ModelMBean. + *

    The ModelMBeanConstructorInfo object describes a constructor of the ModelMBean. * It is a subclass of MBeanConstructorInfo with the addition of an associated Descriptor - * and an implementation of the DescriptorAccess interface. - *

    - *

    - * The fields in the descriptor are defined, but not limited to, the following: 

    - * name : constructor name - * descriptorType : must be "operation" - * role : must be "constructor" - * displayName : human readable name of constructor - * visibility : 1-4 where 1: always visible 4: rarely visible - * presentationString : xml formatted string to describe how to present operation - *

    + * and an implementation of the DescriptorAccess interface.

    + * + *

    + * The fields in the descriptor are defined, but not limited to, the following. + * Note that when the Type in this table is Number, a String that is the decimal + * representation of a Long can also be used.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NameTypeMeaning
    nameStringConstructor name.
    descriptorTypeStringMust be "operation".
    roleStringMust be "constructor".
    displayNameStringHuman readable name of constructor.
    visibilityNumber1-4 where 1: always visible 4: rarely visible.
    presentationStringStringXML formatted string to describe how to present operation
    * *

    The {@code persistPolicy} and {@code currencyTimeLimit} fields - * are meaningless for constructors, but are not considered invalid. + * are meaningless for constructors, but are not considered invalid.

    * *

    The default descriptor will have the {@code name}, {@code * descriptorType}, {@code displayName} and {@code role} fields. The @@ -152,7 +163,7 @@ * describing the MBean constructor. */ public ModelMBeanConstructorInfo(String description, - Constructor constructorMethod) + Constructor constructorMethod) { super(description, constructorMethod); if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) { @@ -194,7 +205,7 @@ */ public ModelMBeanConstructorInfo(String description, - Constructor constructorMethod, + Constructor constructorMethod, Descriptor descriptor) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfo.java --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -156,29 +156,55 @@ /** - * Returns the ModelMBean's descriptor which contains MBean wide policies. This descriptor contains - * metadata about the MBean and default policies for persistence and caching. - *

    - * The fields in the descriptor are defined, but not limited to, the following: - *

    -     * name           : MBean name
    -     * descriptorType : must be "mbean"
    -     * displayName    : name of attribute to be used in displays
    -     * persistPolicy  : OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never
    -     * persistLocation : The fully qualified directory name where the MBean should be persisted (if appropriate)
    -     * persistFile    : File name into which the MBean should be persisted
    -     * persistPeriod  : seconds - frequency of persist cycle for OnTime and NoMoreOftenThan PersistPolicy
    -     * currencyTimeLimit : how long value is valid, <0 never, =0 always, >0 seconds
    -     * log            : where t: log all notifications f: log no notifications
    -     * logfile        : fully qualified filename to log events to
    -     * visibility     : 1-4 where 1: always visible 4: rarely visible
    -     * export         : name to be used to export/expose this MBean so that it is findable by
    -     *                  other JMX Agents.
    -     * presentationString : xml formatted string to allow presentation of data to be associated with the MBean.
    -     * 
    + *

    Returns the ModelMBean's descriptor which contains MBean wide + * policies. This descriptor contains metadata about the MBean and default + * policies for persistence and caching.

    + * + *

    + * The fields in the descriptor are defined, but not limited to, the + * following. Note that when the Type in this table is Number, a String + * that is the decimal representation of a Long can also be used.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NameTypeMeaning
    nameStringMBean name.
    descriptorTypeStringMust be "mbean".
    displayNameStringName of MBean to be used in displays.
    persistPolicyStringOne of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never. + * See the section "MBean Descriptor Fields" in the JMX specification + * document.
    persistLocationStringThe fully qualified directory name where the MBean should be + * persisted (if appropriate).
    persistFileStringFile name into which the MBean should be persisted.
    persistPeriodNumberFrequency of persist cycle in seconds, for OnTime and + * NoMoreOftenThan PersistPolicy
    currencyTimeLimitNumberHow long cached value is valid: <0 never, =0 always, + * >0 seconds.
    logStringt: log all notifications, f: log no notifications.
    logfileStringFully qualified filename to log events to.
    visibilityNumber1-4 where 1: always visible 4: rarely visible.
    exportStringName to be used to export/expose this MBean so that it is + * findable by other JMX Agents.
    presentationStringStringXML formatted string to allow presentation of data to be + * associated with the MBean.
    + * *

    * The default descriptor is: name=className,descriptorType="mbean", displayName=className, - * persistPolicy="never",log="F",export="F",visibility="1" + * persistPolicy="never",log="F",visibility="1" * If the descriptor does not contain all these fields, they will be added with these default values. * *

    Note: because of inconsistencies in previous versions of @@ -207,7 +233,7 @@ * does a complete replacement of the descriptor, no merging is done. If the descriptor to * set to is null then the default descriptor will be created. * The default descriptor is: name=className,descriptorType="mbean", displayName=className, - * persistPolicy="never",log="F",export="F",visibility="1" + * persistPolicy="never",log="F",visibility="1" * If the descriptor does not contain all these fields, they will be added with these default values. * * See {@link #getMBeanDescriptor getMBeanDescriptor} method javadoc for description of valid field names. diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -46,34 +46,46 @@ import javax.management.RuntimeOperationsException; /** - * The ModelMBeanNotificationInfo object describes a notification emitted + *

    The ModelMBeanNotificationInfo object describes a notification emitted * by a ModelMBean. * It is a subclass of MBeanNotificationInfo with the addition of an - * associated Descriptor and an implementation of the Descriptor interface. - *

    - * The fields in the descriptor are defined, but not limited to, - * the following: - *

    - * name           : notification name
    - * descriptorType : must be "notification"
    - * severity       : 0-6 where 0: unknown; 1: non-recoverable;
    - *                  2: critical, failure; 3: major, severe;
    - *                  4: minor, marginal, error; 5: warning;
    - *                  6: normal, cleared, informative
    - * messageID      : unique key for message text (to allow translation,
    - *                  analysis)
    - * messageText    : text of notification
    - * log            : T - log message F - do not log message
    - * logfile        : string fully qualified file name appropriate for
    - *                  operating system
    - * visibility     : 1-4 where 1: always visible 4: rarely visible
    - * presentationString : xml formatted string to allow presentation of data
    - * 
    - * The default descriptor contains the name, descriptorType, + * associated Descriptor and an implementation of the Descriptor interface.

    + * + *

    + * The fields in the descriptor are defined, but not limited to, the following. + * Note that when the Type in this table is Number, a String that is the decimal + * representation of a Long can also be used.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NameTypeMeaning
    nameStringNotification name.
    descriptorTypeStringMust be "notification".
    severityNumber0-6 where 0: unknown; 1: non-recoverable; + * 2: critical, failure; 3: major, severe; + * 4: minor, marginal, error; 5: warning; + * 6: normal, cleared, informative
    messageIDStringUnique key for message text (to allow translation, analysis).
    messageTextStringText of notification.
    logStringT - log message, F - do not log message.
    logfileStringfully qualified file name appropriate for operating system.
    visibilityNumber1-4 where 1: always visible 4: rarely visible.
    presentationStringStringXML formatted string to allow presentation of data.
    + * + *

    The default descriptor contains the name, descriptorType, * displayName and severity(=6) fields. The default value of the name * and displayName fields is the name of the Notification class (as * specified by the name parameter of the - * ModelMBeanNotificationInfo constructor). + * ModelMBeanNotificationInfo constructor).

    * *

    The serialVersionUID of this class is -7445681389570207141L. * diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java --- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanOperationInfo.java Fri Nov 21 15:10:14 2008 -0500 @@ -49,27 +49,48 @@ import javax.management.RuntimeOperationsException; /** - * The ModelMBeanOperationInfo object describes a management operation of the ModelMBean. - * It is a subclass of MBeanOperationInfo with the addition of an associated Descriptor - * and an implementation of the DescriptorAccess interface. - *

    - *

    - * The fields in the descriptor are defined, but not limited to, the following:
    - * name           : operation name
    - * descriptorType : must be "operation"
    - * class          : class where method is defined (fully qualified)
    - * role           : must be "operation", "getter", or "setter
    - * targetObject   : object on which to execute this method
    - * targetType     : type of object reference for targetObject. Can be:
    - *                  ObjectReference | Handle | EJBHandle | IOR | RMIReference.
    - * value          : cached value for operation
    - * currencyTimeLimit : how long cached value is valid
    - * lastUpdatedTimeStamp : when cached value was set
    - * visibility            : 1-4 where 1: always visible 4: rarely visible
    - * presentationString :  xml formatted string to describe how to present operation
    - * 
    - * The default descriptor will have name, descriptorType, displayName and role fields set. - * The default value of the name and displayName fields is the operation name. + *

    The ModelMBeanOperationInfo object describes a management operation of + * the ModelMBean. It is a subclass of MBeanOperationInfo with the addition + * of an associated Descriptor and an implementation of the DescriptorAccess + * interface.

    + * + *

    + * The fields in the descriptor are defined, but not limited to, the following. + * Note that when the Type in this table is Number, a String that is the decimal + * representation of a Long can also be used.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    NameTypeMeaning
    nameStringOperation name.
    descriptorTypeStringMust be "operation".
    classStringClass where method is defined (fully qualified).
    roleStringMust be "operation", "getter", or "setter".
    targetObjectObjectObject on which to execute this method.
    targetTypeStringtype of object reference for targetObject. Can be: + * ObjectReference | Handle | EJBHandle | IOR | RMIReference.
    valueObjectCached value for operation.
    displayNameStringHuman readable display name of the operation.
    currencyTimeLimitNumberHow long cached value is valid.
    lastUpdatedTimeStampNumberWhen cached value was set.
    visibilityNumber1-4 where 1: always visible 4: rarely visible.
    presentationStringStringXML formatted string to describe how to present operation
    + * + *

    The default descriptor will have name, descriptorType, displayName and + * role fields set. The default value of the name and displayName fields is + * the operation name.

    * *

    Note: because of inconsistencies in previous versions of * this specification, it is recommended not to use negative or zero diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java --- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Nov 21 15:10:14 2008 -0500 @@ -1074,7 +1074,7 @@ } } - final Class targetClass; + final Class targetClass; if (opClassName != null) { try { @@ -1126,20 +1126,20 @@ "resolving " + targetClass.getName() + "." + opMethodName); } - final Class[] argClasses; + final Class[] argClasses; if (sig == null) argClasses = null; else { final ClassLoader targetClassLoader = targetClass.getClassLoader(); - argClasses = new Class[sig.length]; + argClasses = new Class[sig.length]; for (int i = 0; i < sig.length; i++) { if (tracing) { MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(),"resolveMethod", "resolve type " + sig[i]); } - argClasses[i] = (Class) primitiveClassMap.get(sig[i]); + argClasses[i] = (Class) primitiveClassMap.get(sig[i]); if (argClasses[i] == null) { try { argClasses[i] = @@ -1170,7 +1170,7 @@ /* Map e.g. "int" to int.class. Goodness knows how many time this particular wheel has been reinvented. */ - private static final Class[] primitiveClasses = { + private static final Class[] primitiveClasses = { int.class, long.class, boolean.class, double.class, float.class, short.class, byte.class, char.class, }; @@ -1178,7 +1178,7 @@ new HashMap>(); static { for (int i = 0; i < primitiveClasses.length; i++) { - final Class c = primitiveClasses[i]; + final Class c = primitiveClasses[i]; primitiveClassMap.put(c.getName(), c); } } @@ -1645,7 +1645,7 @@ try { ClassLoader cl = response.getClass().getClassLoader(); - Class c = Class.forName(respType, true, cl); + Class c = Class.forName(respType, true, cl); subtype = c.isInstance(response); } catch (Exception e) { subtype = false; @@ -1904,7 +1904,7 @@ if (attrSetMethod == null) { if (attrValue != null) { try { - final Class clazz = loadClass(attrType); + final Class clazz = loadClass(attrType); if (! clazz.isInstance(attrValue)) throw new InvalidAttributeValueException(clazz.getName() + " expected, " + @@ -2044,8 +2044,7 @@ final AttributeList responseList = new AttributeList(); // Go through the list of attributes - for (Iterator i = attributes.iterator(); i.hasNext();) { - final Attribute attr = (Attribute) i.next(); + for (Attribute attr : attributes.asList()) { try { setAttribute(attr); responseList.add(attr); @@ -2799,7 +2798,7 @@ return MBeanServerFactory.getClassLoaderRepository(server); } - private Class loadClass(String className) + private Class loadClass(String className) throws ClassNotFoundException { try { return Class.forName(className); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java --- a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -457,7 +457,11 @@ * All the various flavors of {@code MBeanServer.createMBean} methods * will eventually call this method. A subclass that wishes to * support MBean creation through {@code createMBean} thus only - * needs to provide an implementation for this one method. + * needs to provide an implementation for this one method.

    + * + *

    A subclass implementation of this method should respect the contract + * of the various {@code createMBean} methods in the {@link MBeanServer} + * interface, in particular as regards exception wrapping.

    * * @param className The class name of the MBean to be instantiated. * @param name The object name of the MBean. May be null. @@ -488,6 +492,17 @@ * preRegister (MBeanRegistration * interface) method of the MBean has thrown an exception. The * MBean will not be registered. + * @exception RuntimeMBeanException If the MBean's constructor or its + * {@code preRegister} or {@code postRegister} method threw + * a {@code RuntimeException}. If the postRegister + * (MBeanRegistration interface) method of the MBean throws a + * RuntimeException, the createMBean method will + * throw a RuntimeMBeanException, although the MBean creation + * and registration succeeded. In such a case, the MBean will be actually + * registered even though the createMBean method + * threw an exception. Note that RuntimeMBeanException can + * also be thrown by preRegister, in which case the MBean + * will not be registered. * @exception MBeanException The constructor of the MBean has * thrown an exception * @exception NotCompliantMBeanException This class is not a JMX @@ -1096,7 +1111,7 @@ MBeanRegistrationException, MBeanException, NotCompliantMBeanException { try { - return safeCreateMBean(className, name, null, params, signature, true); + return createMBean(className, name, null, params, signature, true); } catch (InstanceNotFoundException ex) { // should not happen! throw new MBeanException(ex, "Unexpected exception: " + ex); @@ -1113,7 +1128,7 @@ throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { - return safeCreateMBean(className, name, loaderName, params, signature, false); + return createMBean(className, name, loaderName, params, signature, false); } /** @@ -1126,7 +1141,7 @@ MBeanRegistrationException, MBeanException, NotCompliantMBeanException { try { - return safeCreateMBean(className, name, null, null, null, true); + return createMBean(className, name, null, null, null, true); } catch (InstanceNotFoundException ex) { // should not happen! throw new MBeanException(ex, "Unexpected exception: " + ex); @@ -1143,32 +1158,7 @@ throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException { - return safeCreateMBean(className, name, loaderName, null, null, false); - } - - // make sure all exceptions are correctly wrapped in a JMXException - private ObjectInstance safeCreateMBean(String className, - ObjectName name, ObjectName loaderName, Object[] params, - String[] signature, boolean useRepository) - throws ReflectionException, InstanceAlreadyExistsException, - MBeanRegistrationException, MBeanException, - NotCompliantMBeanException, InstanceNotFoundException { - try { - return createMBean(className, name, loaderName, params, - signature, useRepository); - } catch (ReflectionException x) { throw x; - } catch (InstanceAlreadyExistsException x) { throw x; - } catch (MBeanRegistrationException x) { throw x; - } catch (MBeanException x) { throw x; - } catch (NotCompliantMBeanException x) { throw x; - } catch (InstanceNotFoundException x) { throw x; - } catch (SecurityException x) { throw x; - } catch (JMRuntimeException x) { throw x; - } catch (RuntimeException x) { - throw new RuntimeOperationsException(x, x.toString()); - } catch (Exception x) { - throw new MBeanException(x, x.toString()); - } + return createMBean(className, name, loaderName, null, null, false); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/ArrayType.java --- a/jdk/src/share/classes/javax/management/openmbean/ArrayType.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/ArrayType.java Fri Nov 21 15:10:14 2008 -0500 @@ -296,7 +296,7 @@ // Check and construct state specific to ArrayType // if (elementType.isArray()) { - ArrayType at = (ArrayType) elementType; + ArrayType at = (ArrayType) elementType; this.dimension = at.getDimension() + dimension; this.elementType = at.getElementOpenType(); this.primitiveArray = at.isPrimitiveArray(); @@ -384,7 +384,7 @@ /* Package-private constructor for callers we trust to get it right. */ ArrayType(String className, String typeName, String description, - int dimension, OpenType elementType, + int dimension, OpenType elementType, boolean primitiveArray) { super(className, typeName, description, true); this.dimension = dimension; @@ -397,7 +397,7 @@ throws OpenDataException { boolean isPrimitiveArray = false; if (elementType.isArray()) { - isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray(); + isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray(); } return buildArrayClassName(dimension, elementType, isPrimitiveArray); } @@ -443,7 +443,7 @@ throws OpenDataException { boolean isPrimitiveArray = false; if (elementType.isArray()) { - isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray(); + isPrimitiveArray = ((ArrayType) elementType).isPrimitiveArray(); } return buildArrayDescription(dimension, elementType, isPrimitiveArray); } @@ -453,7 +453,7 @@ boolean isPrimitiveArray) throws OpenDataException { if (elementType.isArray()) { - ArrayType at = (ArrayType) elementType; + ArrayType at = (ArrayType) elementType; dimension += at.getDimension(); elementType = at.getElementOpenType(); isPrimitiveArray = at.isPrimitiveArray(); @@ -551,7 +551,7 @@ return false; } - Class objClass = obj.getClass(); + Class objClass = obj.getClass(); String objClassName = objClass.getName(); // if obj is not an array, return false @@ -636,8 +636,8 @@ } @Override - boolean isAssignableFrom(OpenType ot) { - if (!(ot instanceof ArrayType)) + boolean isAssignableFrom(OpenType ot) { + if (!(ot instanceof ArrayType)) return false; ArrayType at = (ArrayType) ot; return (at.getDimension() == getDimension() && @@ -675,9 +675,9 @@ // if obj is not an ArrayType, return false // - if (!(obj instanceof ArrayType)) + if (!(obj instanceof ArrayType)) return false; - ArrayType other = (ArrayType) obj; + ArrayType other = (ArrayType) obj; // if other's dimension is different than this instance's, return false // @@ -879,6 +879,7 @@ // Build primitive array // try { + @SuppressWarnings("rawtypes") ArrayType at = new ArrayType(simpleType, true); if (n > 1) at = new ArrayType(n - 1, at); @@ -934,7 +935,7 @@ } } - private ArrayType convertFromWrapperToPrimitiveTypes() { + private ArrayType convertFromWrapperToPrimitiveTypes() { String cn = getClassName(); String tn = getTypeName(); String d = getDescription(); @@ -952,8 +953,8 @@ break; } } - return new ArrayType(cn, tn, d, - dimension, elementType, primitiveArray); + return new ArrayType(cn, tn, d, + dimension, elementType, primitiveArray); } /** @@ -1002,7 +1003,7 @@ } } - private ArrayType convertFromPrimitiveToWrapperTypes() { + private ArrayType convertFromPrimitiveToWrapperTypes() { String cn = getClassName(); String tn = getTypeName(); String d = getDescription(); @@ -1020,7 +1021,7 @@ break; } } - return new ArrayType(cn, tn, d, - dimension, elementType, primitiveArray); + return new ArrayType(cn, tn, d, + dimension, elementType, primitiveArray); } } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java --- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java Fri Nov 21 15:10:14 2008 -0500 @@ -236,8 +236,8 @@ if (other == null) return false; - final Class proxyClass = proxy.getClass(); - final Class otherClass = other.getClass(); + final Class proxyClass = proxy.getClass(); + final Class otherClass = other.getClass(); if (proxyClass != otherClass) return false; InvocationHandler otherih = Proxy.getInvocationHandler(other); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/CompositeType.java --- a/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/CompositeType.java Fri Nov 21 15:10:14 2008 -0500 @@ -329,7 +329,7 @@ * @return true if {@code ot} is assignable to this open type. */ @Override - boolean isAssignableFrom(OpenType ot) { + boolean isAssignableFrom(OpenType ot) { if (!(ot instanceof CompositeType)) return false; CompositeType ct = (CompositeType) ot; @@ -420,9 +420,7 @@ if (myHashCode == null) { int value = 0; value += this.getTypeName().hashCode(); - String key; - for (Iterator k = nameToDescription.keySet().iterator(); k.hasNext(); ) { - key = (String) k.next(); + for (String key : nameToDescription.keySet()) { value += key.hashCode(); value += this.nameToType.get(key).hashCode(); } @@ -457,10 +455,10 @@ result.append(getTypeName()); result.append(",items=("); int i=0; - Iterator k=nameToType.keySet().iterator(); + Iterator k=nameToType.keySet().iterator(); String key; while (k.hasNext()) { - key = (String) k.next(); + key = k.next(); if (i > 0) result.append(","); result.append("(itemName="); result.append(key); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java --- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -78,12 +78,12 @@ /** * @serial The open mbean attribute's min value */ - private final Comparable minValue; + private final Comparable minValue; /** * @serial The open mbean attribute's max value */ - private final Comparable maxValue; + private final Comparable maxValue; // As this instance is immutable, these two values need only @@ -450,7 +450,7 @@ } static void check(OpenMBeanParameterInfo info) throws OpenDataException { - OpenType openType = info.getOpenType(); + OpenType openType = info.getOpenType(); if (openType == null) throw new IllegalArgumentException("OpenType cannot be null"); @@ -562,7 +562,7 @@ } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) static int compare(Object x, Object y) { return ((Comparable) x).compareTo(y); } @@ -657,11 +657,11 @@ return result; } - static Comparable comparableValueFrom(Descriptor d, String name, - OpenType openType) { + static Comparable comparableValueFrom(Descriptor d, String name, + OpenType openType) { T t = valueFrom(d, name, openType); if (t == null || t instanceof Comparable) - return (Comparable) t; + return (Comparable) t; final String msg = "Descriptor field " + name + " with value " + t + " is not Comparable"; @@ -925,7 +925,7 @@ return isValue(this, obj); } - @SuppressWarnings("unchecked") // cast to Comparable + @SuppressWarnings({"unchecked", "rawtypes"}) // cast to Comparable static boolean isValue(OpenMBeanParameterInfo info, Object obj) { if (info.hasDefaultValue() && obj == null) return true; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/OpenMBeanParameterInfoSupport.java --- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanParameterInfoSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanParameterInfoSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -74,12 +74,12 @@ /** * @serial The open mbean parameter's min value */ - private Comparable minValue = null; + private Comparable minValue = null; /** * @serial The open mbean parameter's max value */ - private Comparable maxValue = null; + private Comparable maxValue = null; // As this instance is immutable, these two values need only diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/OpenType.java --- a/jdk/src/share/classes/javax/management/openmbean/OpenType.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/OpenType.java Fri Nov 21 15:10:14 2008 -0500 @@ -206,7 +206,7 @@ } } - private static boolean overridesGetClassName(final Class c) { + private static boolean overridesGetClassName(final Class c) { return AccessController.doPrivileged(new PrivilegedAction() { public Boolean run() { try { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/SimpleType.java --- a/jdk/src/share/classes/javax/management/openmbean/SimpleType.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/SimpleType.java Fri Nov 21 15:10:14 2008 -0500 @@ -163,7 +163,7 @@ public static final SimpleType OBJECTNAME = new SimpleType(ObjectName.class); - private static final SimpleType[] typeArray = { + private static final SimpleType[] typeArray = { VOID, BOOLEAN, CHARACTER, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, STRING, BIGDECIMAL, BIGINTEGER, DATE, OBJECTNAME, }; @@ -232,10 +232,10 @@ return (this == obj); */ - if (!(obj instanceof SimpleType)) + if (!(obj instanceof SimpleType)) return false; - SimpleType other = (SimpleType) obj; + SimpleType other = (SimpleType) obj; // Test if other's className field is the same as for this instance // @@ -290,11 +290,11 @@ return myToString; } - private static final Map canonicalTypes = - new HashMap(); + private static final Map,SimpleType> canonicalTypes = + new HashMap,SimpleType>(); static { for (int i = 0; i < typeArray.length; i++) { - final SimpleType type = typeArray[i]; + final SimpleType type = typeArray[i]; canonicalTypes.put(type, type); } } @@ -310,7 +310,7 @@ * resolved. */ public Object readResolve() throws ObjectStreamException { - final SimpleType canonical = canonicalTypes.get(this); + final SimpleType canonical = canonicalTypes.get(this); if (canonical == null) { // Should not happen throw new InvalidObjectException("Invalid SimpleType: " + this); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java --- a/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/TabularDataSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -30,6 +30,7 @@ // java import // import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.mbeanserver.Util; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; @@ -611,7 +612,7 @@ @SuppressWarnings("unchecked") // historical confusion about the return type public Collection values() { - return (Collection) dataMap.values() ; + return Util.cast(dataMap.values()); } @@ -647,7 +648,7 @@ @SuppressWarnings("unchecked") // historical confusion about the return type public Set> entrySet() { - return (Set) dataMap.entrySet(); + return Util.cast(dataMap.entrySet()); } @@ -725,8 +726,7 @@ if (this.size() != other.size()) { return false; } - for (Iterator iter = this.values().iterator(); iter.hasNext(); ) { - CompositeData value = (CompositeData) iter.next(); + for (CompositeData value : dataMap.values()) { if ( ! other.containsValue(value) ) { return false; } @@ -760,9 +760,8 @@ int result = 0; result += this.tabularType.hashCode(); - for (Iterator iter = this.values().iterator(); iter.hasNext(); ) { - result += ((CompositeData)iter.next()).hashCode(); - } + for (Object value : values()) + result += value.hashCode(); return result; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/openmbean/TabularType.java --- a/jdk/src/share/classes/javax/management/openmbean/TabularType.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/openmbean/TabularType.java Fri Nov 21 15:10:14 2008 -0500 @@ -237,7 +237,7 @@ } @Override - boolean isAssignableFrom(OpenType ot) { + boolean isAssignableFrom(OpenType ot) { if (!(ot instanceof TabularType)) return false; TabularType tt = (TabularType) ot; @@ -329,9 +329,8 @@ int value = 0; value += this.getTypeName().hashCode(); value += this.rowType.hashCode(); - for (Iterator k = indexNames.iterator(); k.hasNext(); ) { - value += k.next().hashCode(); - } + for (String index : indexNames) + value += index.hashCode(); myHashCode = Integer.valueOf(value); } @@ -364,12 +363,10 @@ .append(",rowType=") .append(rowType.toString()) .append(",indexNames=("); - int i=0; - Iterator k = indexNames.iterator(); - while( k.hasNext() ) { - if (i > 0) result.append(","); - result.append(k.next().toString()); - i++; + String sep = ""; + for (String index : indexNames) { + result.append(sep).append(index); + sep = ","; } result.append("))"); myToString = result.toString(); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/MBeanServerNotificationFilter.java --- a/jdk/src/share/classes/javax/management/relation/MBeanServerNotificationFilter.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/MBeanServerNotificationFilter.java Fri Nov 21 15:10:14 2008 -0500 @@ -354,7 +354,7 @@ // Checks the type first String ntfType = notif.getType(); - Vector enabledTypes = getEnabledTypes(); + Vector enabledTypes = getEnabledTypes(); if (!(enabledTypes.contains(ntfType))) { RELATION_LOGGER.logp(Level.FINER, MBeanServerNotificationFilter.class.getName(), @@ -464,8 +464,8 @@ // Serializes this instance in the old serial form // ObjectOutputStream.PutField fields = out.putFields(); - fields.put("mySelectObjNameList", (Vector)selectedNames); - fields.put("myDeselectObjNameList", (Vector)deselectedNames); + fields.put("mySelectObjNameList", selectedNames); + fields.put("myDeselectObjNameList", deselectedNames); out.writeFields(); } else diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RelationService.java --- a/jdk/src/share/classes/javax/management/relation/RelationService.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RelationService.java Fri Nov 21 15:10:14 2008 -0500 @@ -1111,7 +1111,7 @@ throw new IllegalArgumentException(excMsg); } - if (!(oldValue instanceof ArrayList)) + if (!(oldValue instanceof ArrayList)) oldValue = new ArrayList(oldValue); RELATION_LOGGER.entering(RelationService.class.getName(), @@ -1881,7 +1881,7 @@ "getRole", params, signature)); - if (invokeResult == null || invokeResult instanceof ArrayList) + if (invokeResult == null || invokeResult instanceof ArrayList) result = invokeResult; else result = new ArrayList(invokeResult); @@ -2786,7 +2786,7 @@ // Note that it is possible that the MBean has already been removed // from the internal map: this is the case when the MBean is // unregistered, the role is updated, then we arrive here. - HashMap mbeanRefMap = (HashMap) + Map> mbeanRefMap = (myRefedMBeanObjName2RelIdsMap.get(objectName)); if (mbeanRefMap == null) { @@ -2796,11 +2796,11 @@ return true; } - ArrayList roleNames = new ArrayList(); + List roleNames = null; if (!allRolesFlag) { // Now retrieves the roles of current relation where the MBean // was referenced - roleNames = (ArrayList)(mbeanRefMap.get(relationId)); + roleNames = mbeanRefMap.get(relationId); // Removes obsolete reference to role int obsRefIdx = roleNames.indexOf(roleName); @@ -2840,8 +2840,8 @@ // // -exception RelationServiceNotRegisteredException if the Relation // Service is not registered in the MBean Server. - private void updateUnregistrationListener(List newRefList, - List obsoleteRefList) + private void updateUnregistrationListener(List newRefList, + List obsoleteRefList) throws RelationServiceNotRegisteredException { if (newRefList != null && obsoleteRefList != null) { @@ -2871,24 +2871,14 @@ // Enables ObjectNames in newRefList if (newRefList != null) { - for (Iterator newRefIter = newRefList.iterator(); - newRefIter.hasNext();) { - - ObjectName newObjName = (ObjectName) - (newRefIter.next()); + for (ObjectName newObjName : newRefList) myUnregNtfFilter.enableObjectName(newObjName); - } } if (obsoleteRefList != null) { // Disables ObjectNames in obsoleteRefList - for (Iterator obsRefIter = obsoleteRefList.iterator(); - obsRefIter.hasNext();) { - - ObjectName obsObjName = (ObjectName) - (obsRefIter.next()); + for (ObjectName obsObjName : obsoleteRefList) myUnregNtfFilter.disableObjectName(obsObjName); - } } // Under test @@ -3047,18 +3037,13 @@ // to see which roles have not been initialized // Note: no need to test if list not null before cloning, not allowed // to have an empty relation type. - ArrayList roleInfoList = (ArrayList) - (((ArrayList)(relType.getRoleInfos())).clone()); + List roleInfoList = new ArrayList(relType.getRoleInfos()); if (roleList != null) { - for (Iterator roleIter = roleList.iterator(); - roleIter.hasNext();) { - - Role currRole = (Role)(roleIter.next()); + for (Role currRole : roleList.asList()) { String currRoleName = currRole.getRoleName(); - ArrayList currRoleValue = (ArrayList) - (currRole.getRoleValue()); + List currRoleValue = currRole.getRoleValue(); // Retrieves corresponding role info // Can throw a RoleInfoNotFoundException to be converted into a // RoleNotFoundException @@ -3137,9 +3122,7 @@ // Only role list parameter used, as default initialization of roles // done automatically in initializeMissingRoles() sets each // uninitialized role to an empty value. - for (Iterator roleIter = roleList.iterator(); - roleIter.hasNext();) { - Role currRole = (Role)(roleIter.next()); + for (Role currRole : roleList.asList()) { // Creates a dummy empty ArrayList of ObjectNames to be the old // role value :) List dummyList = new ArrayList(); @@ -3191,7 +3174,7 @@ // -exception IllegalArgumentException if null parameter private Integer checkRoleInt(int chkType, String roleName, - List roleValue, + List roleValue, RoleInfo roleInfo, boolean writeChkFlag) throws IllegalArgumentException { @@ -3266,9 +3249,7 @@ // registered in the same MBean Server. String expClassName = roleInfo.getRefMBeanClassName(); - for (Iterator refMBeanIter = roleValue.iterator(); - refMBeanIter.hasNext();) { - ObjectName currObjName = (ObjectName)(refMBeanIter.next()); + for (ObjectName currObjName : roleValue) { // Checks it is registered if (currObjName == null) { @@ -3330,7 +3311,7 @@ ObjectName relationObjName, String relationId, String relationTypeName, - List roleInfoList) + List roleInfoList) throws IllegalArgumentException, RelationServiceNotRegisteredException, InvalidRoleValueException { @@ -3361,10 +3342,8 @@ // with an empty list of ObjectNames. // A check is performed to verify that the role can be set to an // empty value, according to its minimum cardinality - for (Iterator roleInfoIter = roleInfoList.iterator(); - roleInfoIter.hasNext();) { - - RoleInfo currRoleInfo = (RoleInfo)(roleInfoIter.next()); + for (RoleInfo currRoleInfo : roleInfoList) { + String roleName = currRoleInfo.getName(); // Creates an empty value @@ -3663,7 +3642,7 @@ // not exist in the relation private void handleReferenceUnregistration(String relationId, ObjectName objectName, - List roleNameList) + List roleNameList) throws IllegalArgumentException, RelationServiceNotRegisteredException, RelationNotFoundException, @@ -3694,14 +3673,12 @@ // Flag to specify if the relation has to be deleted boolean deleteRelFlag = false; - for (Iterator roleNameIter = roleNameList.iterator(); - roleNameIter.hasNext();) { + for (String currRoleName : roleNameList) { if (deleteRelFlag) { break; } - String currRoleName = (String)(roleNameIter.next()); // Retrieves number of MBeans currently referenced in role // BEWARE! Do not use getRole() as role may be not readable // @@ -3753,10 +3730,7 @@ // using setRole(). So the Relation Service will update the // myRefedMBeanObjName2RelIdsMap to refelect the new role // value! - for (Iterator roleNameIter = roleNameList.iterator(); - roleNameIter.hasNext();) { - - String currRoleName = (String)(roleNameIter.next()); + for (String currRoleName : roleNameList) { if (relObj instanceof RelationSupport) { // Internal relation diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RelationSupport.java --- a/jdk/src/share/classes/javax/management/relation/RelationSupport.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RelationSupport.java Fri Nov 21 15:10:14 2008 -0500 @@ -108,7 +108,7 @@ // via Relation Service setRole() and setRoles() methods // - if the relation is internal to the Relation Service, via // setRoleInt() and setRolesInt() methods. - private Map myRoleName2ValueMap = new HashMap(); + private final Map myRoleName2ValueMap = new HashMap(); // Flag to indicate if the object has been added in the Relation Service private final AtomicBoolean myInRelServFlg = new AtomicBoolean(); @@ -424,7 +424,7 @@ } } - ArrayList roleValue = (ArrayList)(role.getRoleValue()); + List roleValue = role.getRoleValue(); RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getRoleCardinality"); @@ -855,8 +855,7 @@ // Note: no need to test if role value (list) not null before // cloning, null value not allowed, empty list if // nothing. - result = (ArrayList) - (((ArrayList)(role.getRoleValue())).clone()); + result = new ArrayList(role.getRoleValue()); } else { // Role retrieved during multi-role retrieval: returns the @@ -1492,10 +1491,7 @@ RoleList roleList = new RoleList(); RoleUnresolvedList roleUnresList = new RoleUnresolvedList(); - for (Iterator roleIter = list.iterator(); - roleIter.hasNext();) { - - Role currRole = (Role)(roleIter.next()); + for (Role currRole : list.asList()) { Object currResult = null; // Can throw: @@ -1617,12 +1613,10 @@ synchronized(myRoleName2ValueMap) { - for (Iterator roleIter = list.iterator(); - roleIter.hasNext();) { + for (Role currRole : list.asList()) { // No need to check if role is null, it is not allowed to store // a null role in a RoleList :) - Role currRole = (Role)(roleIter.next()); String currRoleName = currRole.getRoleName(); if (myRoleName2ValueMap.containsKey(currRoleName)) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/Role.java --- a/jdk/src/share/classes/javax/management/relation/Role.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/Role.java Fri Nov 21 15:10:14 2008 -0500 @@ -228,9 +228,9 @@ public String toString() { StringBuilder result = new StringBuilder(); result.append("role name: " + name + "; role value: "); - for (Iterator objNameIter = objectNameList.iterator(); + for (Iterator objNameIter = objectNameList.iterator(); objNameIter.hasNext();) { - ObjectName currObjName = (ObjectName)(objNameIter.next()); + ObjectName currObjName = objNameIter.next(); result.append(currObjName.toString()); if (objNameIter.hasNext()) { result.append(", "); @@ -325,7 +325,7 @@ // ObjectOutputStream.PutField fields = out.putFields(); fields.put("myName", name); - fields.put("myObjNameList", (ArrayList)objectNameList); + fields.put("myObjNameList", objectNameList); out.writeFields(); } else diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RoleList.java --- a/jdk/src/share/classes/javax/management/relation/RoleList.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RoleList.java Fri Nov 21 15:10:14 2008 -0500 @@ -25,6 +25,7 @@ package javax.management.relation; +import com.sun.jmx.mbeanserver.Util; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -140,7 +141,7 @@ checkTypeSafe(this); typeSafe = true; } - return (List) (List) this; + return Util.cast(this); } // diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RoleResult.java --- a/jdk/src/share/classes/javax/management/relation/RoleResult.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RoleResult.java Fri Nov 21 15:10:14 2008 -0500 @@ -172,7 +172,7 @@ roleList = new RoleList(); - for (Iterator roleIter = list.iterator(); + for (Iterator roleIter = list.iterator(); roleIter.hasNext();) { Role currRole = (Role)(roleIter.next()); roleList.add((Role)(currRole.clone())); @@ -195,7 +195,7 @@ unresolvedRoleList = new RoleUnresolvedList(); - for (Iterator roleUnresIter = unresolvedList.iterator(); + for (Iterator roleUnresIter = unresolvedList.iterator(); roleUnresIter.hasNext();) { RoleUnresolved currRoleUnres = (RoleUnresolved)(roleUnresIter.next()); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RoleUnresolved.java --- a/jdk/src/share/classes/javax/management/relation/RoleUnresolved.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RoleUnresolved.java Fri Nov 21 15:10:14 2008 -0500 @@ -285,9 +285,9 @@ result.append("role name: " + roleName); if (roleValue != null) { result.append("; value: "); - for (Iterator objNameIter = roleValue.iterator(); + for (Iterator objNameIter = roleValue.iterator(); objNameIter.hasNext();) { - ObjectName currObjName = (ObjectName)(objNameIter.next()); + ObjectName currObjName = objNameIter.next(); result.append(currObjName.toString()); if (objNameIter.hasNext()) { result.append(", "); @@ -344,7 +344,7 @@ // ObjectOutputStream.PutField fields = out.putFields(); fields.put("myRoleName", roleName); - fields.put("myRoleValue", (ArrayList)roleValue); + fields.put("myRoleValue", roleValue); fields.put("myPbType", problemType); out.writeFields(); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/relation/RoleUnresolvedList.java --- a/jdk/src/share/classes/javax/management/relation/RoleUnresolvedList.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/relation/RoleUnresolvedList.java Fri Nov 21 15:10:14 2008 -0500 @@ -25,6 +25,7 @@ package javax.management.relation; +import com.sun.jmx.mbeanserver.Util; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -140,7 +141,7 @@ checkTypeSafe(this); typeSafe = true; } - return (List) (List) this; + return Util.cast(this); } // diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java --- a/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/JMXConnectorFactory.java Fri Nov 21 15:10:14 2008 -0500 @@ -367,7 +367,8 @@ return provider.newJMXConnector(serviceURL, fixedenv); } - private static String resolvePkgs(Map env) throws JMXProviderException { + private static String resolvePkgs(Map env) + throws JMXProviderException { Object pkgsObject = null; @@ -521,7 +522,7 @@ return null; } - static ClassLoader resolveClassLoader(Map environment) { + static ClassLoader resolveClassLoader(Map environment) { ClassLoader loader = null; if (environment != null) { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java --- a/jdk/src/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Fri Nov 21 15:10:14 2008 -0500 @@ -118,7 +118,8 @@ * if it is one of the classes whose byte code we have, or * delegate the load if it is one of the referenced classes. */ - protected Class findClass(String name) throws ClassNotFoundException { + @Override + protected Class findClass(String name) throws ClassNotFoundException { for (int i = 0; i < classNames.length; i++) { if (name.equals(classNames[i])) { return defineClass(classNames[i], byteCodes[i], 0, diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/RMIConnection.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnection.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnection.java Fri Nov 21 15:10:14 2008 -0500 @@ -31,7 +31,6 @@ import java.rmi.Remote; import java.util.Set; -import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.InstanceAlreadyExistsException; @@ -45,11 +44,11 @@ import javax.management.MBeanServerConnection; import javax.management.NotCompliantMBeanException; -import javax.management.NotificationFilter; import javax.management.ObjectInstance; import javax.management.ObjectName; -import javax.management.QueryExp; import javax.management.ReflectionException; +import javax.management.RuntimeMBeanException; +import javax.management.RuntimeOperationsException; import javax.management.remote.NotificationResult; import javax.security.auth.Subject; @@ -89,8 +88,9 @@ * even though it would add useful information to the documentation. The * reason is that it was only added in Mustang (Java SE 6), whereas versions * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our - * commitments for JSR 255. + * commitments for JSR 255. This is also why we suppress rawtypes warnings. */ +@SuppressWarnings("rawtypes") public interface RMIConnection extends Closeable, Remote { /** *

    Returns the connection ID. This string is different for diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Fri Nov 21 15:10:14 2008 -0500 @@ -308,6 +308,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public ObjectInstance createMBean(String className, ObjectName name, MarshalledObject params, @@ -368,6 +369,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, @@ -493,6 +495,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public Set queryMBeans(ObjectName name, MarshalledObject query, @@ -527,6 +530,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public Set queryNames(ObjectName name, MarshalledObject query, @@ -668,6 +672,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public void setAttribute(ObjectName name, MarshalledObject attribute, Subject delegationSubject) @@ -720,6 +725,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public AttributeList setAttributes(ObjectName name, MarshalledObject attributes, Subject delegationSubject) @@ -765,6 +771,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public Object invoke(ObjectName name, String operationName, MarshalledObject params, @@ -928,6 +935,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public Integer[] addNotificationListeners(ObjectName[] names, MarshalledObject[] filters, Subject[] delegationSubjects) @@ -1013,6 +1021,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public void addNotificationListener(ObjectName name, ObjectName listener, MarshalledObject filter, @@ -1148,6 +1157,7 @@ } } + @SuppressWarnings("rawtypes") // MarshalledObject public void removeNotificationListener(ObjectName name, ObjectName listener, MarshalledObject filter, @@ -1809,7 +1819,7 @@ } } - private static T unwrap(final MarshalledObject mo, + private static T unwrap(final MarshalledObject mo, final ClassLoader cl, final Class wrappedClass) throws IOException { @@ -1847,7 +1857,7 @@ return null; } - private static T unwrap(final MarshalledObject mo, + private static T unwrap(final MarshalledObject mo, final ClassLoader cl1, final ClassLoader cl2, final Class wrappedClass) diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Fri Nov 21 15:10:14 2008 -0500 @@ -28,6 +28,7 @@ import com.sun.jmx.event.DaemonThreadFactory; import com.sun.jmx.event.EventConnection; import com.sun.jmx.mbeanserver.PerThreadGroupPool; +import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.internal.ClientCommunicatorAdmin; import com.sun.jmx.remote.internal.ClientListenerInfo; import com.sun.jmx.remote.internal.ClientNotifForwarder; @@ -584,7 +585,7 @@ // added for re-connection private Integer addListenerWithSubject(ObjectName name, - MarshalledObject filter, + MarshalledObject filter, Subject delegationSubject, boolean reconnect) throws InstanceNotFoundException, IOException { @@ -595,7 +596,8 @@ "(ObjectName,MarshalledObject,Subject)"); final ObjectName[] names = new ObjectName[] {name}; - final MarshalledObject[] filters = new MarshalledObject[] {filter}; + final MarshalledObject[] filters = + Util.cast(new MarshalledObject[] {filter}); final Subject[] delegationSubjects = new Subject[] { delegationSubject }; @@ -611,7 +613,7 @@ // added for re-connection private Integer[] addListenersWithSubjects(ObjectName[] names, - MarshalledObject[] filters, + MarshalledObject[] filters, Subject[] delegationSubjects, boolean reconnect) throws InstanceNotFoundException, IOException { @@ -1362,7 +1364,7 @@ //-------------------------------------------------------------------- private class RMINotifClient extends ClientNotifForwarder { - public RMINotifClient(ClassLoader cl, Map env) { + public RMINotifClient(ClassLoader cl, Map env) { super(cl, env); } @@ -1444,8 +1446,8 @@ Integer[] listenerIDs; final ObjectName[] names = new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME}; - final MarshalledObject[] filters = - new MarshalledObject[] {sFilter}; + final MarshalledObject[] filters = + Util.cast(new MarshalledObject[] {sFilter}); final Subject[] subjects = new Subject[] {null}; try { listenerIDs = @@ -1580,7 +1582,8 @@ final ObjectName[] names = new ObjectName[len]; final NotificationListener[] listeners = new NotificationListener[len]; final NotificationFilter[] filters = new NotificationFilter[len]; - final MarshalledObject[] mFilters = new MarshalledObject[len]; + final MarshalledObject[] mFilters = + Util.cast(new MarshalledObject[len]); final Object[] handbacks = new Object[len]; for (i=0;i environment) throws IOException { if (rmiServer instanceof javax.rmi.CORBA.Stub) { javax.rmi.CORBA.Stub stub = (javax.rmi.CORBA.Stub) rmiServer; @@ -1776,7 +1779,7 @@ * does not point to an {@link org.omg.CORBA.ORB ORB}. * @exception IOException if the ORB initialization failed. **/ - static ORB resolveOrb(Map environment) + static ORB resolveOrb(Map environment) throws IOException { if (environment != null) { final Object orb = environment.get(EnvHelp.DEFAULT_ORB); @@ -2004,7 +2007,7 @@ } } - private RMIServer findRMIServerIIOP(String ior, Map env, boolean isIiop) { + private RMIServer findRMIServerIIOP(String ior, Map env, boolean isIiop) { // could forbid "rmi:" URL here -- but do we need to? final ORB orb = (ORB) env.get(EnvHelp.DEFAULT_ORB); @@ -2012,7 +2015,7 @@ return (RMIServer) PortableRemoteObject.narrow(stub, RMIServer.class); } - private RMIServer findRMIServerJRMP(String base64, Map env, boolean isIiop) + private RMIServer findRMIServerJRMP(String base64, Map env, boolean isIiop) throws IOException { // could forbid "iiop:" URL here -- but do we need to? final byte[] serialized; @@ -2046,7 +2049,8 @@ this.loader = cl; } - protected Class resolveClass(ObjectStreamClass classDesc) + @Override + protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { return Class.forName(classDesc.getName(), false, loader); } @@ -2121,13 +2125,13 @@ private static final String rmiServerImplStubClassName = RMIServer.class.getName() + "Impl_Stub"; - private static final Class rmiServerImplStubClass; + private static final Class rmiServerImplStubClass; private static final String rmiConnectionImplStubClassName = RMIConnection.class.getName() + "Impl_Stub"; private static final Class rmiConnectionImplStubClass; private static final String pRefClassName = "com.sun.jmx.remote.internal.PRef"; - private static final Constructor proxyRefConstructor; + private static final Constructor proxyRefConstructor; static { final String pRefByteCodeString = "\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+ @@ -2162,7 +2166,7 @@ } }; - Class serverStubClass; + Class serverStubClass; try { serverStubClass = Class.forName(rmiServerImplStubClassName); } catch (Exception e) { @@ -2175,10 +2179,10 @@ rmiServerImplStubClass = serverStubClass; Class stubClass; - Constructor constr; + Constructor constr; try { stubClass = Class.forName(rmiConnectionImplStubClassName); - constr = (Constructor) AccessController.doPrivileged(action); + constr = (Constructor) AccessController.doPrivileged(action); } catch (Exception e) { logger.error("", "Failed to initialize proxy reference constructor "+ @@ -2198,9 +2202,8 @@ RemoteRef ref = stub.getRef(); RemoteRef proxyRef = (RemoteRef) proxyRefConstructor.newInstance(new Object[] {ref}); - final Class[] constrTypes = {RemoteRef.class}; - final Constructor rmiConnectionImplStubConstructor = - rmiConnectionImplStubClass.getConstructor(constrTypes); + final Constructor rmiConnectionImplStubConstructor = + rmiConnectionImplStubClass.getConstructor(RemoteRef.class); Object[] args = {proxyRef}; RMIConnection proxyStub = (RMIConnection) rmiConnectionImplStubConstructor.newInstance(args); @@ -2328,7 +2331,7 @@ "com.sun.jmx.remote.internal.ProxyStub"; private static final String pInputStreamClassName = "com.sun.jmx.remote.internal.PInputStream"; - private static final Class proxyStubClass; + private static final Class proxyStubClass; static { final String proxyStubByteCodeString = "\312\376\272\276\0\0\0.\0)\12\0\14\0\26\7\0\27\12\0\14\0\30\12"+ diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Fri Nov 21 15:10:14 2008 -0500 @@ -423,7 +423,7 @@ try { if (tracing) logger.trace("start", "binding to " + jndiUrl); - final Hashtable usemap = EnvHelp.mapToHashtable(attributes); + final Hashtable usemap = EnvHelp.mapToHashtable(attributes); bind(jndiUrl, usemap, objref, rebind); @@ -555,7 +555,7 @@ logger.trace("stop", "unbind from external directory: " + boundJndiUrl); - final Hashtable usemap = EnvHelp.mapToHashtable(attributes); + final Hashtable usemap = EnvHelp.mapToHashtable(attributes); InitialContext ctx = new InitialContext(usemap); @@ -655,7 +655,7 @@ * @param rmiServer The object to bind in the registry * @param rebind true if the object must be rebound. **/ - void bind(String jndiUrl, Hashtable attributes, + void bind(String jndiUrl, Hashtable attributes, RMIServer rmiServer, boolean rebind) throws NamingException, MalformedURLException { // if jndiURL is not null, we nust bind the stub to a @@ -692,7 +692,8 @@ * @param attributes A Map containing environment parameters, * built from the Map specified at this object creation. **/ - private void encodeStubInAddress(RMIServer rmiServer, Map attributes) + private void encodeStubInAddress( + RMIServer rmiServer, Map attributes) throws IOException { final String protocol, host; @@ -735,14 +736,16 @@ /** * Returns the IOR of the given rmiServer. **/ - static String encodeStub(RMIServer rmiServer, Map env) throws IOException { + static String encodeStub( + RMIServer rmiServer, Map env) throws IOException { if (rmiServer instanceof javax.rmi.CORBA.Stub) return "/ior/" + encodeIIOPStub(rmiServer, env); else return "/stub/" + encodeJRMPStub(rmiServer, env); } - static String encodeJRMPStub(RMIServer rmiServer, Map env) + static String encodeJRMPStub( + RMIServer rmiServer, Map env) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oout = new ObjectOutputStream(bout); @@ -752,7 +755,8 @@ return byteArrayToBase64(bytes); } - static String encodeIIOPStub(RMIServer rmiServer, Map env) + static String encodeIIOPStub( + RMIServer rmiServer, Map env) throws IOException { try { javax.rmi.CORBA.Stub stub = @@ -767,7 +771,8 @@ * Object that we will bind to the registry. * This object is a stub connected to our RMIServerImpl. **/ - private static RMIServer objectToBind(RMIServerImpl rmiServer, Map env) + private static RMIServer objectToBind( + RMIServerImpl rmiServer, Map env) throws IOException { return RMIConnector. connectStub((RMIServer)rmiServer.toStub(),env); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIServerImpl.java Fri Nov 21 15:10:14 2008 -0500 @@ -75,7 +75,7 @@ * to an empty Map. */ public RMIServerImpl(Map env) { - this.env = (env == null) ? Collections.EMPTY_MAP : env; + this.env = (env == null) ? Collections.emptyMap() : env; } void setRMIConnectorServer(RMIConnectorServer connServer) @@ -337,8 +337,9 @@ synchronized (clientList) { dropDeadReferences(); - for (Iterator it = clientList.iterator(); it.hasNext(); ) { - WeakReference wr = (WeakReference) it.next(); + for (Iterator> it = clientList.iterator(); + it.hasNext(); ) { + WeakReference wr = it.next(); if (wr.get() == client) { it.remove(); break; @@ -417,9 +418,10 @@ dropDeadReferences(), this will usually be the first element of the list, but a garbage collection could have happened in between. */ - for (Iterator it = clientList.iterator(); it.hasNext(); ) { - WeakReference wr = (WeakReference) it.next(); - RMIConnection client = (RMIConnection) wr.get(); + for (Iterator> it = clientList.iterator(); + it.hasNext(); ) { + WeakReference wr = it.next(); + RMIConnection client = wr.get(); it.remove(); if (client != null) { try { @@ -475,10 +477,10 @@ buf.append("//").append(clientHost); buf.append(" "); if (subject != null) { - Set principals = subject.getPrincipals(); + Set principals = subject.getPrincipals(); String sep = ""; - for (Iterator it = principals.iterator(); it.hasNext(); ) { - Principal p = (Principal) it.next(); + for (Iterator it = principals.iterator(); it.hasNext(); ) { + Principal p = it.next(); String name = p.getName().replace(' ', '_').replace(';', ':'); buf.append(sep).append(name); sep = ";"; @@ -492,8 +494,9 @@ private void dropDeadReferences() { synchronized (clientList) { - for (Iterator it = clientList.iterator(); it.hasNext(); ) { - WeakReference wr = (WeakReference) it.next(); + for (Iterator> it = clientList.iterator(); + it.hasNext(); ) { + WeakReference wr = it.next(); if (wr.get() == null) it.remove(); } @@ -522,7 +525,7 @@ private MBeanServer mbeanServer; - private final Map env; + private final Map env; private RMIConnectorServer connServer; diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/javax/management/timer/Timer.java --- a/jdk/src/share/classes/javax/management/timer/Timer.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/javax/management/timer/Timer.java Fri Nov 21 15:10:14 2008 -0500 @@ -248,8 +248,7 @@ */ public synchronized MBeanNotificationInfo[] getNotificationInfo() { Set notifTypes = new TreeSet(); - for (Iterator it = timerTable.values().iterator(); it.hasNext(); ) { - Object[] entry = (Object[]) it.next(); + for (Object[] entry : timerTable.values()) { TimerNotification notif = (TimerNotification) entry[TIMER_NOTIF_INDEX]; notifTypes.add(notif.getType()); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java --- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Fri Nov 21 15:10:14 2008 -0500 @@ -43,7 +43,7 @@ String method; URI uri; HttpConnection connection; - int reqContentLen; + long reqContentLen; long rspContentLen; /* raw streams which access the socket directly */ InputStream ris; @@ -79,7 +79,7 @@ ServerImpl server; ExchangeImpl ( - String m, URI u, Request req, int len, HttpConnection connection + String m, URI u, Request req, long len, HttpConnection connection ) throws IOException { this.req = req; this.reqHdrs = req.headers(); @@ -148,7 +148,7 @@ if (uis != null) { return uis; } - if (reqContentLen == -1) { + if (reqContentLen == -1L) { uis_orig = new ChunkedInputStream (this, ris); uis = uis_orig; } else { diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java --- a/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Fri Nov 21 15:10:14 2008 -0500 @@ -37,21 +37,21 @@ */ class FixedLengthInputStream extends LeftOverInputStream { - private int remaining; + private long remaining; - FixedLengthInputStream (ExchangeImpl t, InputStream src, int len) { + FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) { super (t, src); this.remaining = len; } protected int readImpl (byte[]b, int off, int len) throws IOException { - eof = (remaining == 0); + eof = (remaining == 0L); if (eof) { return -1; } if (len > remaining) { - len = remaining; + len = (int)remaining; } int n = in.read(b, off, len); if (n > -1) { @@ -65,7 +65,7 @@ return 0; } int n = in.available(); - return n < remaining? n: remaining; + return n < remaining? n: (int)remaining; } public boolean markSupported () {return false;} diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/sun/net/httpserver/Request.java --- a/jdk/src/share/classes/sun/net/httpserver/Request.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/sun/net/httpserver/Request.java Fri Nov 21 15:10:14 2008 -0500 @@ -53,7 +53,7 @@ do { startLine = readLine(); /* skip blank lines */ - } while (startLine.equals ("")); + } while (startLine == null ? false : startLine.equals ("")); } diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/sun/net/httpserver/ServerImpl.java --- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Fri Nov 21 15:10:14 2008 -0500 @@ -470,13 +470,13 @@ String version = requestLine.substring (start); Headers headers = req.headers(); String s = headers.getFirst ("Transfer-encoding"); - int clen = 0; + long clen = 0L; if (s !=null && s.equalsIgnoreCase ("chunked")) { - clen = -1; + clen = -1L; } else { s = headers.getFirst ("Content-Length"); if (s != null) { - clen = Integer.parseInt (s); + clen = Long.parseLong(s); } } ctx = contexts.findContext (protocol, uri.getPath()); diff -r 776009a04496 -r bb12ee0dbc91 jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java Fri Nov 21 15:10:14 2008 -0500 @@ -272,14 +272,14 @@ */ private Method[] getMemberMethods() { if (memberMethods == null) { - final Method[] mm = type.getDeclaredMethods(); - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - AccessibleObject.setAccessible(mm, true); - return null; - } - }); - memberMethods = mm; + memberMethods = AccessController.doPrivileged( + new PrivilegedAction() { + public Method[] run() { + final Method[] mm = type.getDeclaredMethods(); + AccessibleObject.setAccessible(mm, true); + return mm; + } + }); } return memberMethods; } diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/com/sun/net/httpserver/bugs/FixedLengthInputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/net/httpserver/bugs/FixedLengthInputStream.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,172 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6756771 + * @summary com.sun.net.httpserver.HttpServer should handle POSTs larger than 2Gig + */ + +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.InetSocketAddress; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.Socket; +import java.util.logging.*; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class FixedLengthInputStream +{ + static final long POST_SIZE = 4L * 1024L * 1024L * 1024L; // 4Gig + + /* Remove when CR 6755625 is fixed */ + static final String requestHeaders = ((new StringBuilder()) + .append("POST /flis/ HTTP/1.1\r\n") + .append("User-Agent: Java/1.7.0\r\n") + .append("Host: localhost\r\n") + .append("Accept: text/html, image/gif, image/jpeg,") + .append( " *; q=.2, */*; q=.2\r\n") + .append("Content-Length: 4294967296\r\n\r\n")).toString(); + + void test(String[] args) throws IOException { + HttpServer httpServer = startHttpServer(); + int port = httpServer.getAddress().getPort(); + try { + /* Uncomment & when CR 6755625 is fixed, remove socket code + URL url = new URL("http://localhost:" + port + "/flis/"); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + uc.setDoOutput(true); + uc.setRequestMethod("POST"); + uc.setFixedLengthStreamingMode(POST_SIZE); + OutputStream os = uc.getOutputStream(); + */ + + Socket socket = new Socket("localhost", port); + OutputStream os = socket.getOutputStream(); + PrintStream ps = new PrintStream(os); + debug("Request: " + requestHeaders); + ps.print(requestHeaders); + ps.flush(); + + /* create a 32K byte array with data to POST */ + int thirtyTwoK = 32 * 1024; + byte[] ba = new byte[thirtyTwoK]; + for (int i =0; i k = new Object(){}.getClass().getEnclosingClass(); + try {k.getMethod("instanceMain",String[].class) + .invoke( k.newInstance(), (Object) args);} + catch (Throwable e) {throw e.getCause();}} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} + +} diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/java/lang/annotation/ParameterAnnotations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/ParameterAnnotations.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,118 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6761678 + * @summary Check properties of Annotations returned from + * getParameterAnnotations, including freedom from security + * exceptions. + * @author Martin Buchholz + */ + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) +@interface Named { + String value(); +} + +public class ParameterAnnotations { + + // A security policy that differs from the default only in that it + // allows a security manager to be uninstalled. + static class MyPolicy extends Policy { + final Policy defaultPolicy; + MyPolicy(Policy defaultPolicy) { + this.defaultPolicy = defaultPolicy; + } + public boolean implies(ProtectionDomain pd, Permission p) { + return p.getName().equals("setSecurityManager") || + defaultPolicy.implies(pd, p); + } + } + + public void nop(@Named("foo") Object foo, + @Named("bar") Object bar) { + } + + void test(String[] args) throws Throwable { + // Test without a security manager + test1(); + + // Test with a security manager + Policy defaultPolicy = Policy.getPolicy(); + Policy.setPolicy(new MyPolicy(defaultPolicy)); + System.setSecurityManager(new SecurityManager()); + try { + test1(); + } finally { + System.setSecurityManager(null); + Policy.setPolicy(defaultPolicy); + } + } + + void test1() throws Throwable { + for (Method m : thisClass.getMethods()) { + if (m.getName().equals("nop")) { + Annotation[][] ann = m.getParameterAnnotations(); + equal(ann.length, 2); + Annotation foo = ann[0][0]; + Annotation bar = ann[1][0]; + equal(foo.toString(), "@Named(value=foo)"); + equal(bar.toString(), "@Named(value=bar)"); + check(foo.equals(foo)); + check(! foo.equals(bar)); + } + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + static Class thisClass = new Object(){}.getClass().getEnclosingClass(); + public static void main(String[] args) throws Throwable { + try {thisClass.getMethod("instanceMain",String[].class) + .invoke(thisClass.newInstance(), (Object) args);} + catch (Throwable e) {throw e.getCause();}} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java --- a/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/test/javax/management/MBeanServer/MBeanExceptionTest.java Fri Nov 21 15:10:14 2008 -0500 @@ -23,16 +23,19 @@ /* * @test - * @bug 5035217 + * @bug 5035217 6766173 * @summary Test that MBean's RuntimeException is wrapped in * RuntimeMBeanException and (for Standard MBeans) that checked exceptions * are wrapped in MBeanException * @author Eamonn McManus - * @compile -source 1.4 MBeanExceptionTest.java + * @compile MBeanExceptionTest.java * @run main MBeanExceptionTest */ +import java.util.Collections; +import java.util.Set; import javax.management.*; +import javax.management.namespace.MBeanServerSupport; public class MBeanExceptionTest { public static void main(String[] args) throws Exception { @@ -56,6 +59,53 @@ failures += test(mbs, standardName, true); failures += test(mbs, standardMBeanName, true); failures += test(mbs, dynamicName, false); + + final boolean[] booleans = {false, true}; + + for (boolean mbss : booleans) { + for (boolean runtimeX : booleans) { + Class excC = + runtimeX ? RuntimeMBeanException.class : MBeanException.class; + String excS = + runtimeX ? "a RuntimeMBeanException" : "an MBeanException"; + String mbsS = + mbss ? "a conformant MBeanServerSupport" : "a plain MBeanServer"; + MBeanServer xmbs = + mbss ? new CreateExceptionMBS() : mbs; + System.out.println( + "Test that, with " + mbsS + ", " + excS + " is wrapped " + + "in " + excS); + // E.g. "Test that, with a plain MBeanServer, an MBeanException + // is wrapped in an MBeanException". + try { + mbs.createMBean( + Except.class.getName(), new ObjectName(":name=Oops"), + new Object[] {runtimeX}, + new String[] {boolean.class.getName()}); + System.out.println( + "FAIL: createMBean succeeded but should not have"); + failures++; + } catch (Exception e) { + if (!excC.isInstance(e)) { + System.out.println( + "FAIL: expected " + excC.getName() + " from " + + "createMBean, got " + e); + failures++; + } else { + Throwable cause = e.getCause(); + if (!excC.isInstance(cause)) { + System.out.println( + "FAIL: expected " + excC.getName() + + " as cause of " + excC.getName() + + ", got " + e); + failures++; + } else + System.out.println("...ok"); + } + } + } + } + if (failures == 0) System.out.println("Test passed"); else { @@ -153,6 +203,15 @@ } public static class Except implements ExceptMBean { + public Except() {} + + public Except(boolean runtimeX) throws MBeanException { + if (runtimeX) + throw new RuntimeMBeanException(new RuntimeException(), "Bang"); + else + throw new MBeanException(new Exception(), "Bang"); + } + public String getUncheckedException() { throw theUncheckedException; } @@ -221,4 +280,28 @@ private static final RuntimeException theUncheckedException = new UnsupportedOperationException("The unchecked exception " + "that should be seen"); + + private static class CreateExceptionMBS extends MBeanServerSupport { + @Override + protected Set getNames() { + return Collections.emptySet(); + } + + @Override + public DynamicMBean getDynamicMBeanFor(ObjectName name) + throws InstanceNotFoundException { + throw new InstanceNotFoundException(name); + } + + @Override + public ObjectInstance createMBean(String className, + ObjectName name, ObjectName loaderName, Object[] params, + String[] signature, boolean useCLR) + throws ReflectionException, InstanceAlreadyExistsException, + MBeanRegistrationException, MBeanException, + NotCompliantMBeanException, InstanceNotFoundException { + Exception wrapped = new MBeanException(new Exception(), "Bang"); + throw new MBeanException(wrapped, "Bang"); + } + } } diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/javax/management/eventService/CustomForwarderTest.java --- a/jdk/test/javax/management/eventService/CustomForwarderTest.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/test/javax/management/eventService/CustomForwarderTest.java Fri Nov 21 15:10:14 2008 -0500 @@ -23,7 +23,7 @@ /* * @test CustomForwarderTest - * @bug 5108776 + * @bug 5108776 6759619 * @summary Test that a custom EventForwarder can be added * @author Eamonn McManus */ @@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import javax.management.MBeanNotificationInfo; import javax.management.MBeanServer; import javax.management.MBeanServerInvocationHandler; import javax.management.Notification; @@ -107,6 +108,14 @@ socket.close(); } + void simulateNonFatal() { + receiver.nonFatal(new Exception("NonFatal")); + } + + void simulateFailed() { + receiver.failed(new Error("Failed")); + } + private class Receiver implements Runnable { public void run() { byte[] buf = new byte[1024]; @@ -216,16 +225,26 @@ EventClientDelegateMBean.OBJECT_NAME, EventClientDelegateMBean.class, false); - EventRelay relay = new UdpEventRelay(delegate); + UdpEventRelay relay = new UdpEventRelay(delegate); EventClient client = new EventClient(delegate, relay, null, null, 0L); final Semaphore lostCountSema = new Semaphore(0); + final BlockingQueue nonFatalNotifs = + new ArrayBlockingQueue(1); + final BlockingQueue failedNotifs = + new ArrayBlockingQueue(1); NotificationListener lostListener = new NotificationListener() { public void handleNotification(Notification notification, Object handback) { if (notification.getType().equals(EventClient.NOTIFS_LOST)) { System.out.println("Got lost-notifs notif: count=" + notification.getUserData()); lostCountSema.release(((Long) notification.getUserData()).intValue()); + } else if (notification.getType().equals(EventClient.NONFATAL)) { + System.out.println("Got nonFatal notif"); + nonFatalNotifs.add(notification); + } else if (notification.getType().equals(EventClient.FAILED)) { + System.out.println("Got failed notif"); + failedNotifs.add(notification); } else System.out.println("Mysterious EventClient notif: " + notification); } @@ -300,6 +319,35 @@ Thread.sleep(10); assertEquals("Further lost-notifs", 0, lostCountSema.availablePermits()); + System.out.println("Testing error notifs"); + relay.simulateNonFatal(); + n = nonFatalNotifs.poll(10, TimeUnit.SECONDS); + assertEquals("Exception message for non-fatal exception", "NonFatal", + ((Throwable) n.getSource()).getMessage()); + relay.simulateFailed(); + n = failedNotifs.poll(10, TimeUnit.SECONDS); + assertEquals("Exception message for failed exception", "Failed", + ((Throwable) n.getSource()).getMessage()); + + // 6759619 + System.out.println("Test EventClient.getEventClientNotificationInfo"); + MBeanNotificationInfo[] mbnis = client.getEventClientNotificationInfo(); + final String[] expectedTypes = { + EventClient.NOTIFS_LOST, EventClient.NONFATAL, EventClient.FAILED + }; + check: + for (String type : expectedTypes) { + for (MBeanNotificationInfo mbni : mbnis) { + for (String t : mbni.getNotifTypes()) { + if (type.equals(t)) { + System.out.println("...found " + type); + continue check; + } + } + } + throw new Exception("TEST FAILED: Did not find notif type " + type); + } + client.close(); System.out.println("TEST PASSED"); diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/mxbean/ExceptionDiagnosisTest.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,237 @@ +/* + * @test + * @bug 6713777 + * @summary Test that exception messages include all relevant information + * @author Eamonn McManus + */ + +import java.beans.ConstructorProperties; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import javax.management.JMX; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +public class ExceptionDiagnosisTest { + private static volatile String failure; + + // ------ Illegal MXBeans ------ + + // Test that all of BdelloidMXBean, Rotifer, and File appear in the + // exception messages. File is not an allowed type because of recursive + // getters like "File getParentFile()". + public static interface BdelloidMXBean { + public Rotifer getRotifer(); + } + + public static class Bdelloid implements BdelloidMXBean { + public Rotifer getRotifer() { + return null; + } + } + + public static class Rotifer { + public File getFile() { + return null; + } + } + + // Test that all of IndirectHashMapMXBean, HashMapContainer, and + // HashMap appear in the exception messages. + // HashMap is not an allowed type because only the + // java.util interface such as Map are allowed with generic parameters, + // not their concrete implementations like HashMap. + public static interface IndirectHashMapMXBean { + public HashMapContainer getContainer(); + } + + public static class IndirectHashMap implements IndirectHashMapMXBean { + public HashMapContainer getContainer() { + return null; + } + } + + public static class HashMapContainer { + public HashMap getHashMap() {return null;} + } + + // ------ MXBeans that are legal but where proxies are not ------ + + // Test that all of BlimMXBean, BlimContainer, Blim, and Blam appear + // in the exception messages for a proxy for this MXBean. Blam is + // legal in MXBeans but is not reconstructible so you cannot make + // a proxy for BlimMXBean. + public static interface BlimMXBean { + public BlimContainer getBlimContainer(); + } + + public static class BlimImpl implements BlimMXBean { + public BlimContainer getBlimContainer() { + return null; + } + } + + public static class BlimContainer { + public Blim getBlim() {return null;} + public void setBlim(Blim blim) {} + } + + public static class Blim { + public Blam getBlam() {return null;} + public void setBlam(Blam blam) {} + } + + public static class Blam { + public Blam(int x) {} + + public int getX() {return 0;} + } + + + // ------ Property name differing only in case ------ + + public static interface CaseProbMXBean { + public CaseProb getCaseProb(); + } + + public static class CaseProbImpl implements CaseProbMXBean { + public CaseProb getCaseProb() {return null;} + } + + public static class CaseProb { + @ConstructorProperties({"urlPath"}) + public CaseProb(String urlPath) {} + + public String getURLPath() {return null;} + } + + + public static void main(String[] args) throws Exception { + testMXBeans(new Bdelloid(), BdelloidMXBean.class, Rotifer.class, File.class); + testMXBeans(new IndirectHashMap(), + IndirectHashMapMXBean.class, HashMapContainer.class, + HashMapContainer.class.getMethod("getHashMap").getGenericReturnType()); + + testProxies(new BlimImpl(), BlimMXBean.class, BlimMXBean.class, + BlimContainer.class, Blim.class, Blam.class); + + testCaseProb(); + + if (failure == null) + System.out.println("TEST PASSED"); + else + throw new Exception("TEST FAILED: " + failure); + } + + private static void testMXBeans(Object mbean, Type... expectedTypes) + throws Exception { + try { + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + mbs.registerMBean(mbean, name); + fail("No exception from registerMBean for " + mbean); + } catch (NotCompliantMBeanException e) { + checkExceptionChain("MBean " + mbean, e, expectedTypes); + } + } + + private static void testProxies( + Object mbean, Class mxbeanClass, Type... expectedTypes) + throws Exception { + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + mbs.registerMBean(mbean, name); + T proxy = JMX.newMXBeanProxy(mbs, name, mxbeanClass); + List methods = new ArrayList(); + for (Method m : mxbeanClass.getMethods()) { + if (m.getDeclaringClass() == mxbeanClass) + methods.add(m); + } + if (methods.size() != 1) { + fail("TEST BUG: expected to find exactly one method in " + + mxbeanClass.getName() + ": " + methods); + } + Method getter = methods.get(0); + try { + try { + getter.invoke(proxy); + fail("No exception from proxy method " + getter.getName() + + " in " + mxbeanClass.getName()); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + if (cause instanceof Exception) + throw (Exception) cause; + else + throw (Error) cause; + } + } catch (IllegalArgumentException e) { + checkExceptionChain( + "Proxy for " + mxbeanClass.getName(), e, expectedTypes); + } + } + + private static void testCaseProb() throws Exception { + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + Object mbean = new CaseProbImpl(); + mbs.registerMBean(new CaseProbImpl(), name); + CaseProbMXBean proxy = JMX.newMXBeanProxy(mbs, name, CaseProbMXBean.class); + try { + CaseProb prob = proxy.getCaseProb(); + fail("No exception from proxy method getCaseProb"); + } catch (IllegalArgumentException e) { + String messageChain = messageChain(e); + if (messageChain.contains("URLPath")) { + System.out.println("Message chain contains URLPath as required: " + + messageChain); + } else { + fail("Exception chain for CaseProb does not mention property" + + " URLPath differing only in case"); + System.out.println("Full stack trace:"); + e.printStackTrace(System.out); + } + } + } + + private static void checkExceptionChain( + String what, Throwable e, Type[] expectedTypes) { + System.out.println("Exceptions in chain for " + what + ":"); + for (Throwable t = e; t != null; t = t.getCause()) + System.out.println(".." + t); + + String messageChain = messageChain(e); + + // Now check that each of the classes is mentioned in those messages + for (Type type : expectedTypes) { + String name = (type instanceof Class) ? + ((Class) type).getName() : type.toString(); + if (!messageChain.contains(name)) { + fail("Exception chain for " + what + " does not mention " + + name); + System.out.println("Full stack trace:"); + e.printStackTrace(System.out); + } + } + + System.out.println(); + } + + private static String messageChain(Throwable t) { + String msg = "//"; + for ( ; t != null; t = t.getCause()) + msg += " " + t.getMessage() + " //"; + return msg; + } + + private static void fail(String why) { + failure = why; + System.out.println("FAIL: " + why); + } +} diff -r 776009a04496 -r bb12ee0dbc91 jdk/test/javax/management/mxbean/TypeNameTest.java --- a/jdk/test/javax/management/mxbean/TypeNameTest.java Fri Nov 21 08:09:11 2008 -0800 +++ b/jdk/test/javax/management/mxbean/TypeNameTest.java Fri Nov 21 15:10:14 2008 -0500 @@ -23,7 +23,7 @@ /* * @test - * @bug 6757225 + * @bug 6757225 6763051 * @summary Test that type names in MXBeans match their spec. * @author Eamonn McManus */ @@ -40,6 +40,8 @@ import javax.management.MBeanServerFactory; import javax.management.ObjectName; import javax.management.StandardMBean; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularType; public class TypeNameTest { public static interface TestMXBean { @@ -63,7 +65,7 @@ } }; - static String failure; + static volatile String failure; public static void main(String[] args) throws Exception { TestMXBean testImpl = (TestMXBean) Proxy.newProxyInstance( @@ -74,24 +76,46 @@ mbs.registerMBean(mxbean, name); MBeanInfo mbi = mbs.getMBeanInfo(name); MBeanAttributeInfo[] mbais = mbi.getAttributes(); + boolean sawTabular = false; for (MBeanAttributeInfo mbai : mbais) { String attrName = mbai.getName(); String attrTypeName = (String) mbai.getDescriptor().getFieldValue("originalType"); String fieldName = attrName + "Name"; Field nameField = TestMXBean.class.getField(fieldName); String expectedTypeName = (String) nameField.get(null); + if (expectedTypeName.equals(attrTypeName)) { System.out.println("OK: " + attrName + ": " + attrTypeName); } else { - failure = "For attribute " + attrName + " expected type name \"" + + fail("For attribute " + attrName + " expected type name \"" + expectedTypeName + "\", found type name \"" + attrTypeName + - "\""; - System.out.println("FAIL: " + failure); + "\""); + } + + if (mbai.getType().equals(TabularData.class.getName())) { + sawTabular = true; + TabularType tt = (TabularType) mbai.getDescriptor().getFieldValue("openType"); + if (tt.getTypeName().equals(attrTypeName)) { + System.out.println("OK: TabularType name for " + attrName); + } else { + fail("For attribute " + attrName + " expected TabularType " + + "name \"" + attrTypeName + "\", found \"" + + tt.getTypeName()); + } } } + + if (!sawTabular) + fail("Test bug: did not test TabularType name"); + if (failure == null) System.out.println("TEST PASSED"); else throw new Exception("TEST FAILED: " + failure); } + + private static void fail(String why) { + System.out.println("FAIL: " + why); + failure = why; + } } diff -r 776009a04496 -r bb12ee0dbc91 langtools/.hgtags --- a/langtools/.hgtags Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/.hgtags Fri Nov 21 15:10:14 2008 -0500 @@ -13,3 +13,4 @@ 258af9b67b7cb4262ab1b5424160c9ad22d52e8f jdk7-b36 24a47c3062fe8869fcfb533ce0ff770c8ceb550d jdk7-b37 3fd42dfa6f27f2767a241fb82bc01a613f0c2096 jdk7-b38 +3fb51e47622bb771571680bc6a7b64c6172b482d jdk7-b39 diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java --- a/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/api/Formattable.java Fri Nov 21 15:10:14 2008 -0500 @@ -49,4 +49,23 @@ * @return a string representing the object's kind */ String getKind(); + + static class LocalizedString implements Formattable { + String key; + + public LocalizedString(String key) { + this.key = key; + } + + public String toString(java.util.Locale l, Messages messages) { + return messages.getLocalizedString(l, key); + } + public String getKind() { + return "LocalizedString"; + } + + public String toString() { + return key; + } + } } diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Nov 21 15:10:14 2008 -0500 @@ -361,6 +361,8 @@ for (Symbol sup = clazz; sup != null && sup != this.owner; sup = types.supertype(sup.type).tsym) { + while (sup.type.tag == TYPEVAR) + sup = sup.type.getUpperBound().tsym; if (sup.type.isErroneous()) return true; // error recovery if ((sup.flags() & COMPOUND) != 0) @@ -1183,7 +1185,9 @@ * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { - for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) { + for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) { + while (t.tag == TYPEVAR) + t = t.getUpperBound(); TypeSymbol c = t.tsym; for (Scope.Entry e = c.members().lookup(name); e.scope != null; diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/code/Type.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Nov 21 15:10:14 2008 -0500 @@ -360,17 +360,6 @@ public boolean isUnbound() { return false; } public Type withTypeVar(Type t) { return this; } - public static List removeBounds(List ts) { - ListBuffer result = new ListBuffer(); - for(;ts.nonEmpty(); ts = ts.tail) { - result.append(ts.head.removeBounds()); - } - return result.toList(); - } - public Type removeBounds() { - return this; - } - /** The underlying method type of this type. */ public MethodType asMethodType() { throw new AssertionError(); } @@ -489,10 +478,6 @@ return new WildcardType(t, kind, tsym, bound); } - public Type removeBounds() { - return isUnbound() ? this : type; - } - public Type getExtendsBound() { if (kind == EXTENDS) return type; diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Nov 21 15:10:14 2008 -0500 @@ -709,16 +709,13 @@ case UNDETVAR: if (s.tag == WILDCARD) { UndetVar undetvar = (UndetVar)t; - - // Because of wildcard capture, s must be on the left - // hand side of an assignment. Furthermore, t is an - // underconstrained type variable, for example, one - // that is only used in the return type of a method. - // If the type variable is truly underconstrained, it - // cannot have any low bounds: - assert undetvar.lobounds.isEmpty() : undetvar; - undetvar.inst = glb(upperBound(s), undetvar.inst); + // We should check instantiated type against any of the + // undetvar's lower bounds. + for (Type t2 : undetvar.lobounds) { + if (!isSubtype(t2, undetvar.inst)) + return false; + } return true; } else { return isSameType(t, s); @@ -3367,33 +3364,67 @@ * quantifiers) only */ private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) { - ListBuffer from = new ListBuffer(); - ListBuffer to = new ListBuffer(); - adaptSelf(t, from, to); - ListBuffer rewritten = new ListBuffer(); - List formals = from.toList(); - boolean changed = false; - for (Type arg : to.toList()) { - Type bound; - if (rewriteTypeVars && arg.tag == TYPEVAR) { - TypeVar tv = (TypeVar)arg; - bound = high ? tv.bound : syms.botType; - } else { - bound = high ? upperBound(arg) : lowerBound(arg); + return new Rewriter(high, rewriteTypeVars).rewrite(t); + } + + class Rewriter extends UnaryVisitor { + + boolean high; + boolean rewriteTypeVars; + + Rewriter(boolean high, boolean rewriteTypeVars) { + this.high = high; + this.rewriteTypeVars = rewriteTypeVars; + } + + Type rewrite(Type t) { + ListBuffer from = new ListBuffer(); + ListBuffer to = new ListBuffer(); + adaptSelf(t, from, to); + ListBuffer rewritten = new ListBuffer(); + List formals = from.toList(); + boolean changed = false; + for (Type arg : to.toList()) { + Type bound = visit(arg); + if (arg != bound) { + changed = true; + bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head) + : makeSuperWildcard(bound, (TypeVar)formals.head); + } + rewritten.append(bound); + formals = formals.tail; } - Type newarg = bound; - if (arg != bound) { - changed = true; - newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head) - : makeSuperWildcard(bound, (TypeVar)formals.head); - } - rewritten.append(newarg); - formals = formals.tail; + if (changed) + return subst(t.tsym.type, from.toList(), rewritten.toList()); + else + return t; + } + + public Type visitType(Type t, Void s) { + return high ? upperBound(t) : lowerBound(t); + } + + @Override + public Type visitCapturedType(CapturedType t, Void s) { + return visitWildcardType(t.wildcard, null); } - if (changed) - return subst(t.tsym.type, from.toList(), rewritten.toList()); - else - return t; + + @Override + public Type visitTypeVar(TypeVar t, Void s) { + if (rewriteTypeVars) + return high ? t.bound : syms.botType; + else + return t; + } + + @Override + public Type visitWildcardType(WildcardType t, Void s) { + Type bound = high ? t.getExtendsBound() : + t.getSuperBound(); + if (bound == null) + bound = high ? syms.objectType : syms.botType; + return bound; + } } /** diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 21 15:10:14 2008 -0500 @@ -706,13 +706,13 @@ } } - // Check that the variable's declared type is well-formed. - chk.validate(tree.vartype, env); - VarSymbol v = tree.sym; Lint lint = env.info.lint.augment(v.attributes_field, v.flags()); Lint prevLint = chk.setLint(lint); + // Check that the variable's declared type is well-formed. + chk.validate(tree.vartype, env); + try { chk.checkDeprecatedAnnotation(tree.pos(), v); @@ -2007,6 +2007,10 @@ log.error(pos, "type.var.cant.be.deref"); return syms.errSymbol; } else { + Symbol sym2 = (sym.flags() & Flags.PRIVATE) != 0 ? + rs.new AccessError(env, site, sym) : + sym; + rs.access(sym2, pos, site, name, true); return sym; } case ERROR: @@ -2374,16 +2378,14 @@ } if (warned && sym.type.tag == FORALL) { - String typeargs = ""; - if (typeargtypes != null && typeargtypes.nonEmpty()) { - typeargs = "<" + Type.toString(typeargtypes) + ">"; - } chk.warnUnchecked(env.tree.pos(), "unchecked.meth.invocation.applied", - sym, - sym.location(), - typeargs, - Type.toString(argtypes)); + kindName(sym), + sym.name, + rs.methodArguments(sym.type.getParameterTypes()), + rs.methodArguments(argtypes), + kindName(sym.location()), + sym.location()); owntype = new MethodType(owntype.getParameterTypes(), types.erasure(owntype.getReturnType()), owntype.getThrownTypes(), @@ -2516,7 +2518,10 @@ // accept class or interface or typevar as first bound. Type b = checkBase(bs.head, tree.bounds.head, env, false, false, false); boundSet.add(types.erasure(b)); - if (b.tag == TYPEVAR) { + if (b.isErroneous()) { + a.bound = b; + } + else if (b.tag == TYPEVAR) { // if first bound was a typevar, do not accept further bounds. if (tree.bounds.tail.nonEmpty()) { log.error(tree.bounds.tail.head.pos(), @@ -2530,7 +2535,9 @@ for (JCExpression bound : tree.bounds.tail) { bs = bs.tail; Type i = checkBase(bs.head, bound, env, false, true, false); - if (i.tag == CLASS) + if (i.isErroneous()) + a.bound = i; + else if (i.tag == CLASS) chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet); } } diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Nov 21 15:10:14 2008 -0500 @@ -424,43 +424,43 @@ * @param bs The bound. */ private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) { - if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) { - CapturedType ct = (CapturedType)a; - boolean ok; - if (ct.bound.isErroneous()) {//capture doesn't exist - ok = false; + if (a.isUnbound()) { + return; + } else if (a.tag != WILDCARD) { + a = types.upperBound(a); + for (List l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { + if (!types.isSubtype(a, l.head)) { + log.error(pos, "not.within.bounds", a); + return; + } + } + } else if (a.isExtendsBound()) { + if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings)) + log.error(pos, "not.within.bounds", a); + } else if (a.isSuperBound()) { + if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound())) + log.error(pos, "not.within.bounds", a); + } + } + + /** Check that a type is within some bounds. + * + * Used in TypeApply to verify that, e.g., X in V is a valid + * type argument. + * @param pos Position to be used for error reporting. + * @param a The type that should be bounded by bs. + * @param bs The bound. + */ + private void checkCapture(JCTypeApply tree) { + List args = tree.getTypeArguments(); + for (Type arg : types.capture(tree.type).getTypeArguments()) { + if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous()) { + log.error(args.head.pos, "not.within.bounds", args.head.type); + break; } - else { - switch (ct.wildcard.kind) { - case EXTENDS: - ok = types.isCastable(bs.getUpperBound(), - types.upperBound(a), - Warner.noWarnings); - break; - case SUPER: - ok = !types.notSoftSubtype(types.lowerBound(a), - bs.getUpperBound()); - break; - case UNBOUND: - ok = true; - break; - default: - throw new AssertionError("Invalid bound kind"); - } - } - if (!ok) - log.error(pos, "not.within.bounds", a); + args = args.tail; } - else { - a = types.upperBound(a); - for (List l = types.getBounds(bs); l.nonEmpty(); l = l.tail) { - if (!types.isSubtype(a, l.head)) { - log.error(pos, "not.within.bounds", a); - return; - } - } - } - } + } /** Check that type is different from 'void'. * @param pos Position to be used for error reporting. @@ -802,10 +802,10 @@ public void visitTypeApply(JCTypeApply tree) { if (tree.type.tag == CLASS) { - List formals = tree.type.tsym.type.getTypeArguments(); - List actuals = types.capture(tree.type).getTypeArguments(); + List formals = tree.type.tsym.type.allparams(); + List actuals = tree.type.allparams(); List args = tree.arguments; - List forms = formals; + List forms = tree.type.tsym.type.getTypeArguments(); ListBuffer tvars_buf = new ListBuffer(); // For matching pairs of actual argument types `a' and @@ -826,24 +826,28 @@ } args = tree.arguments; + List tvars_cap = types.substBounds(formals, + formals, + types.capture(tree.type).allparams()); + while (args.nonEmpty() && tvars_cap.nonEmpty()) { + // Let the actual arguments know their bound + args.head.type.withTypeVar((TypeVar)tvars_cap.head); + args = args.tail; + tvars_cap = tvars_cap.tail; + } + + args = tree.arguments; List tvars = tvars_buf.toList(); + while (args.nonEmpty() && tvars.nonEmpty()) { - // Let the actual arguments know their bound - args.head.type.withTypeVar(tvars.head); + checkExtends(args.head.pos(), + args.head.type, + tvars.head); args = args.tail; tvars = tvars.tail; } - args = tree.arguments; - tvars = tvars_buf.toList(); - while (args.nonEmpty() && tvars.nonEmpty()) { - checkExtends(args.head.pos(), - actuals.head, - tvars.head); - args = args.tail; - tvars = tvars.tail; - actuals = actuals.tail; - } + checkCapture(tree); // Check that this type is either fully parameterized, or // not parameterized at all. diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Nov 21 15:10:14 2008 -0500 @@ -30,6 +30,8 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.tree.*; +import com.sun.tools.javac.api.Formattable.LocalizedString; +import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Symbol.*; @@ -40,6 +42,9 @@ import static com.sun.tools.javac.code.TypeTags.*; import javax.lang.model.element.ElementVisitor; +import java.util.Map; +import java.util.HashMap; + /** Helper class for name resolution, used mostly by the attribution phase. * *

    This is NOT part of any API supported by Sun Microsystems. If @@ -554,7 +559,6 @@ boolean useVarargs, boolean operator) { if (sym.kind == ERR) return bestSoFar; - if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; assert sym.kind < AMBIGUOUS; try { if (rawInstantiate(env, site, sym, argtypes, typeargtypes, @@ -651,8 +655,9 @@ // both abstract or both concrete if (!m1Abstract && !m2Abstract) return new AmbiguityError(m1, m2); - // check for same erasure - if (!types.isSameType(m1.erasure(types), m2.erasure(types))) + // check that both signatures have the same erasure + if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), + m2.erasure(types).getParameterTypes())) return new AmbiguityError(m1, m2); // both abstract, neither overridden; merge throws clause and result type Symbol result; @@ -1192,15 +1197,23 @@ Name name, List argtypes, List typeargtypes) { - Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false); - if (varargsEnabled && sym.kind >= WRONG_MTHS) { - sym = findFun(env, name, argtypes, typeargtypes, true, false); - if (sym.kind >= WRONG_MTHS) - sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true); + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + sym = findFun(env, name, argtypes, typeargtypes, + steps.head.isBoxingRequired, + env.info.varArgs = steps.head.isVarargsRequired); + methodResolutionCache.put(steps.head, sym); + steps = steps.tail; } - if (sym.kind >= AMBIGUOUS) { - sym = access( - sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); + if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error + MethodResolutionPhase errPhase = + firstErroneousResolutionPhase(); + sym = access(methodResolutionCache.get(errPhase), + pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired; } return sym; } @@ -1217,17 +1230,23 @@ Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env env, Type site, Name name, List argtypes, List typeargtypes) { - Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false, - env.info.varArgs=false, false); - if (varargsEnabled && sym.kind >= WRONG_MTHS) { - sym = findMethod(env, site, name, argtypes, typeargtypes, true, - false, false); - if (sym.kind >= WRONG_MTHS) - sym = findMethod(env, site, name, argtypes, typeargtypes, true, - env.info.varArgs=true, false); + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + sym = findMethod(env, site, name, argtypes, typeargtypes, + steps.head.isBoxingRequired(), + env.info.varArgs = steps.head.isVarargsRequired(), false); + methodResolutionCache.put(steps.head, sym); + steps = steps.tail; } - if (sym.kind >= AMBIGUOUS) { - sym = access(sym, pos, site, name, true, argtypes, typeargtypes); + if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error + MethodResolutionPhase errPhase = + firstErroneousResolutionPhase(); + sym = access(methodResolutionCache.get(errPhase), + pos, site, name, true, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired; } return sym; } @@ -1268,14 +1287,22 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, false, env.info.varArgs=false); - if (varargsEnabled && sym.kind >= WRONG_MTHS) { - sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, false); - if (sym.kind >= WRONG_MTHS) - sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, env.info.varArgs=true); + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, + steps.head.isBoxingRequired(), + env.info.varArgs = steps.head.isVarargsRequired()); + methodResolutionCache.put(steps.head, sym); + steps = steps.tail; } - if (sym.kind >= AMBIGUOUS) { - sym = access(sym, pos, site, names.init, true, argtypes, typeargtypes); + if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error + MethodResolutionPhase errPhase = firstErroneousResolutionPhase(); + sym = access(methodResolutionCache.get(errPhase), + pos, site, names.init, true, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired(); } return sym; } @@ -1452,6 +1479,12 @@ error.report(log, tree.pos(), type.getEnclosingType(), null, null, null); } + private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args"); + + public Object methodArguments(List argtypes) { + return argtypes.isEmpty() ? noArgs : argtypes; + } + /** Root class for resolve errors. * Instances of this class indicate "Symbol not found". * Instances of subclass indicate other errors. @@ -1558,8 +1591,8 @@ "cant.apply.symbol" + (explanation != null ? ".1" : ""), kindname, ws.name == names.init ? ws.owner.name : ws.name, - ws.type.getParameterTypes(), - argtypes, + methodArguments(ws.type.getParameterTypes()), + methodArguments(argtypes), kindName(ws.owner), ws.owner.type, explanation); @@ -1733,4 +1766,50 @@ pair.sym2.location(site, types)); } } + + enum MethodResolutionPhase { + BASIC(false, false), + BOX(true, false), + VARARITY(true, true); + + boolean isBoxingRequired; + boolean isVarargsRequired; + + MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) { + this.isBoxingRequired = isBoxingRequired; + this.isVarargsRequired = isVarargsRequired; + } + + public boolean isBoxingRequired() { + return isBoxingRequired; + } + + public boolean isVarargsRequired() { + return isVarargsRequired; + } + + public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) { + return (varargsEnabled || !isVarargsRequired) && + (boxingEnabled || !isBoxingRequired); + } + } + + private Map methodResolutionCache = + new HashMap(MethodResolutionPhase.values().length); + + final List methodResolutionSteps = List.of(BASIC, BOX, VARARITY); + + private MethodResolutionPhase firstErroneousResolutionPhase() { + MethodResolutionPhase bestSoFar = BASIC; + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= WRONG_MTHS) { + sym = methodResolutionCache.get(steps.head); + bestSoFar = steps.head; + steps = steps.tail; + } + return bestSoFar; + } } diff -r 776009a04496 -r bb12ee0dbc91 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 21 15:10:14 2008 -0500 @@ -745,7 +745,10 @@ compiler.warn.unchecked.cast.to.type=\ [unchecked] unchecked cast to type {0} compiler.warn.unchecked.meth.invocation.applied=\ - [unchecked] unchecked method invocation: {0} in {1} is applied to {2}({3}) + [unchecked] unchecked method invocation: {0} {1} in {4} {5} is applied to given types\n\ + required: {2}\n\ + found: {3} + compiler.warn.unchecked.generic.array.creation=\ [unchecked] unchecked generic array creation of type {0} for varargs parameter @@ -771,7 +774,7 @@ Cannot find annotation method ''{1}()'' in type ''{0}'': {2} compiler.warn.raw.class.use=\ - [raw-type] found raw type: {0}\n\ + [rawtypes] found raw type: {0}\n\ missing type parameters for generic class {1} ##### @@ -1062,6 +1065,9 @@ package ##### +compiler.misc.no.args=\ + no arguments + compiler.err.override.static=\ {0}; overriding method is static compiler.err.override.meth=\ diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/6304921/T6304921.out --- a/langtools/test/tools/javac/6304921/T6304921.out Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/test/tools/javac/6304921/T6304921.out Fri Nov 21 15:10:14 2008 -0500 @@ -1,4 +1,4 @@ -T6304921.java:671/671/680: warning: [raw-type] found raw type: java.util.ArrayList +T6304921.java:671/671/680: warning: [rawtypes] found raw type: java.util.ArrayList missing type parameters for generic class java.util.ArrayList List list = new ArrayList(); ^ diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/6758789/T6758789a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6758789/T6758789a.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6758789 + * @summary 6758789: Some method resolution diagnostic should be improved + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6758789a.out -XDrawDiagnostics T6758789a.java + */ + +class T6758789a { + void m1() {} + void m2(int i) {} + void test() { + m1(1); + m2(); + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/6758789/T6758789a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6758789/T6758789a.out Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,3 @@ +T6758789a.java:37:9: compiler.err.cant.apply.symbol: kindname.method, m1, compiler.misc.no.args, int, kindname.class, T6758789a, null +T6758789a.java:38:9: compiler.err.cant.apply.symbol: kindname.method, m2, int, compiler.misc.no.args, kindname.class, T6758789a, null +2 errors \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/6758789/T6758789b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6758789/T6758789b.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6758789 + * @summary 6758789: Some method resolution diagnostic should be improved + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6758789b.out -Werror -XDrawDiagnostics -Xlint:unchecked T6758789b.java + */ + +class T6758789a { + class Foo {} + + void m(Foo foo) {} + + void test() { + m(new Foo()); + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/6758789/T6758789b.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/6758789/T6758789b.out Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,3 @@ +T6758789b.java:39:11: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo +T6758789b.java:39:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo, T6758789a.Foo, kindname.class, T6758789a +2 warnings diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/cast/6548436/T6548436a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/cast/6548436/T6548436a.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6548436 + * @summary Incorrect inconvertible types error + * @author Maurizio Cimadamore + * + * @compile T6548436a.java + */ + +public class T6548436a { + + static class Base> {} + + static void test(Base je) { + Object o = (Base)je; + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/cast/6548436/T6548436b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/cast/6548436/T6548436b.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6548436 + * @summary Incorrect inconvertible types error + * @author Maurizio Cimadamore + * + * @compile T6548436b.java + */ + +public class T6548436b { + + enum E { } + + static void test(Enum o) { + Object e = (E)o; + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/cast/6548436/T6548436c.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/cast/6548436/T6548436c.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,42 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6548436 + * @summary Incorrect inconvertible types error + * @author Maurizio Cimadamore + * + * @compile T6548436c.java + */ + +public class T6548436c { + + interface A> { } + + interface B extends A { } + + static void test(A a) { + Object o = (B)a; + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/cast/6548436/T6548436d.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/cast/6548436/T6548436d.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6548436 + * @summary Incorrect inconvertible types error + * @author Maurizio Cimadamore + * + * @compile/fail T6548436d.java + */ + +public class T6548436d { + + static class Base> {} + + static void test(Base je) { + Object o = (Base)je; + } +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6487370/T6487370.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/6487370/T6487370.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,56 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6487370 + * @author Maurizio Cimadamore + * @summary javac incorrectly gives ambiguity warning with override-equivalent abstract inherited methods + */ + +public class T6487370 { + + interface I1 { + String m(Number n); + } + + interface I2 { + Object m(Number n); + } + + static abstract class X implements I1, I2 { + String test() { + return m(0.0f); + } + } + + static class W extends X { + public String m(Number n) { + return "Hello!"; + } + } + + public static void main(String args[]) { + System.out.println(new W().test()); + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6531090/T6531090b.java --- a/langtools/test/tools/javac/generics/6531090/T6531090b.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/test/tools/javac/generics/6531090/T6531090b.java Fri Nov 21 15:10:14 2008 -0500 @@ -23,7 +23,7 @@ /* * @test - * @bug 6531090 + * @bug 6531090 6711619 * * @summary Cannot access methods/fields of a captured type belonging to an intersection type * @author Maurizio Cimadamore @@ -32,12 +32,20 @@ public class T6531090b { static class A { - public void a() {} - public A a; + public void a1() {} + protected void a2() {} + void a3() {} + public A a1; + protected A a2; + A a3; } static class B extends A { - public void b(){} - public B b; + public void b1() {} + protected void b2() {} + void b3() {} + public B b1; + protected B b2; + B b3; } static interface I{ void i(); @@ -65,18 +73,35 @@ } static void testMemberMethods(C arg) { - arg.t.a(); - arg.t.b(); + arg.t.a1(); + arg.t.a2(); + arg.t.a3(); + arg.t.b1(); + arg.t.b2(); + arg.t.b3(); arg.t.i1(); - arg.w.a(); - arg.w.b(); + arg.w.a1(); + arg.w.a2(); + arg.w.a3(); + arg.w.b1(); + arg.w.b2(); + arg.w.b3(); arg.w.i1(); } static void testMemberFields(C arg) { - A ta = arg.t.a; - B tb = arg.t.b; - A wa = arg.w.a; - B wb = arg.w.b; + A ta; B tb; + ta = arg.t.a1; + ta = arg.t.a2; + ta = arg.t.a3; + tb = arg.t.b1; + tb = arg.t.b2; + tb = arg.t.b3; + ta = arg.w.a1; + ta = arg.w.a2; + ta = arg.w.a3; + tb = arg.w.b1; + tb = arg.w.b2; + tb = arg.w.b3; } } diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6711619/T6711619a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/6711619/T6711619a.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,74 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6711619 + * + * @summary javac doesn't allow access to protected members in intersection types + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6711619a.out -XDrawDiagnostics T6711619a.java + */ +class T6711619a { + + static class A { + private void a() {} + private A a; + } + static class B extends A { + private B b() {} + private B b; + } + static interface I{ + void i(); + } + static interface I1{ + void i1(); + } + static class E extends B implements I, I1{ + public void i() {} + public void i1() {} + } + static class C{ + T t; + W w; + C(W w, T t) { + this.w = w; + this.t = t; + } + } + + static void testMemberMethods(C arg) { + arg.t.a(); + arg.t.b(); + } + + static void testMemberFields(C arg) { + A ta; B tb; + ta = arg.t.a; + tb = arg.t.b; + ta = arg.w.a; + tb = arg.w.b; + } +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6711619/T6711619a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/6711619/T6711619a.out Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,7 @@ +T6711619a.java:63:14: compiler.err.report.access: a(), private, T6711619a.A +T6711619a.java:64:14: compiler.err.report.access: b(), private, T6711619a.B +T6711619a.java:69:19: compiler.err.report.access: a, private, T6711619a.A +T6711619a.java:70:19: compiler.err.report.access: b, private, T6711619a.B +T6711619a.java:71:19: compiler.err.report.access: a, private, T6711619a.A +T6711619a.java:72:19: compiler.err.report.access: b, private, T6711619a.B +6 errors diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6711619/T6711619b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/6711619/T6711619b.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,64 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6711619 + * + * @summary javac doesn't allow access to protected members in intersection types + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6711619b.out -XDrawDiagnostics T6711619b.java + */ + +class T6711619b { + static class X1> { + private int i; + E e; + int f() { + return e.i; + } + } + + static class X2> { + static private int i; + int f() { + return E.i; + } + } + + static class X3 & java.io.Serializable> { + private int i; + E e; + int f() { + return e.i; + } + } + + static class X4 & java.io.Serializable> { + static private int i; + int f() { + return E.i; + } + } +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/6711619/T6711619b.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/6711619/T6711619b.out Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,5 @@ +T6711619b.java:39:22: compiler.err.report.access: i, private, T6711619b.X1 +T6711619b.java:46:22: compiler.err.report.access: i, private, T6711619b.X2 +T6711619b.java:54:22: compiler.err.report.access: i, private, T6711619b.X3 +T6711619b.java:61:22: compiler.err.report.access: i, private, T6711619b.X4 +4 errors diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/T6557954.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/T6557954.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,36 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6557954 + * @summary Inner class type parameters doesn't get substituted when checking type well-formedness + * @author Maurizio Cimadamore + * + * @compile T6557954.java + */ + +class T6557954 { + class Foo {} + T6557954.Foo f; +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/inference/6718364/T6718364.out --- a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out Fri Nov 21 15:10:14 2008 -0500 @@ -1,3 +1,3 @@ T6718364.java:36:32: compiler.warn.prob.found.req: (- compiler.misc.unchecked.assign), T6718364.X, T6718364.X -T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: m(T6718364.X,T), T6718364, , T6718364.X>,T6718364.X +T6718364.java:36:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6718364.X,T, T6718364.X>,T6718364.X, kindname.class, T6718364 2 warnings \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/typevars/6680106/T6680106.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,40 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6680106 + * @summary StackOverFlowError for Cyclic inheritance in TypeParameters with ArrayType Bounds + * @author Maurizio Cimadamore + * @compile/fail/ref=T6680106.out -XDrawDiagnostics T6680106.java + */ + +class T6680106 { + class A0 {} + class A1 {} + class A2 {} + class A3 {} + class A5 {} + class A6 {} + class A7 {} +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/typevars/6680106/T6680106.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/typevars/6680106/T6680106.out Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,13 @@ +T6680106.java:34:25: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +T6680106.java:35:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class) +T6680106.java:35:40: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +T6680106.java:36:25: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class) +T6680106.java:36:40: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class) +T6680106.java:36:55: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +T6680106.java:37:30: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +T6680106.java:38:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class) +T6680106.java:38:50: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +T6680106.java:39:30: compiler.err.type.found.req: S[], (- compiler.misc.type.req.class) +T6680106.java:39:50: compiler.err.type.found.req: U[], (- compiler.misc.type.req.class) +T6680106.java:39:70: compiler.err.type.found.req: T[], (- compiler.misc.type.req.class) +12 errors \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/wildcards/6651719/T6651719b.java --- a/langtools/test/tools/javac/generics/wildcards/6651719/T6651719b.java Fri Nov 21 08:09:11 2008 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -/* - * @test - * @bug 6651719 - * @summary Compiler crashes possibly during forward reference of TypeParameter - * @compile T6651719b.java - */ -import java.util.*; - -public class T6651719b { - void m(T t, List> list) {} - void test(List> list) { - m("", list); - } -} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/wildcards/6762569/T6762569a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/wildcards/6762569/T6762569a.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6762569 + * @summary Javac crashes with AssertionError in Types.containedBy + * @compile T6762569a.java + */ +import java.util.*; + +class T6762569a { + void m(T t, List> list) {} + + void test(List> list) { + m("", list); + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/wildcards/6762569/T6762569b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/wildcards/6762569/T6762569b.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6762569 + * @summary Javac crashes with AssertionError in Types.containedBy + * @compile/fail T6762569b.java + */ +import java.util.*; + +class T6762569b { + void m(T t, List> list) {} + + void test(List> list) { + m("", list); + } +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/generics/wildcards/T6732484.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/wildcards/T6732484.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,37 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6732484 + * @summary Bound error on wildcard code + * @author Maurizio Cimadamore + * @compile T6732484.java + */ + +class T6732484 { + class A> {} + class B extends A {} + + A f; +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/varargs/T6746184.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/varargs/T6746184.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6746184 + * @summary javac fails to compile call to public varargs method + */ + +public class T6746184 { + public static void main(String[] args) { + A.m(new Object()); + } +} + +class A { + public static void m(final Object... varargs) {} + private static void m(final Object singleArg) {} +} \ No newline at end of file diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javac/warnings/T6763518.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/warnings/T6763518.java Fri Nov 21 15:10:14 2008 -0500 @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6763518 + * @summary Impossible to suppress raw-type warnings + * @compile -Werror -Xlint:rawtypes T6763518.java + */ + +import java.util.List; + +class T6763518 { + @SuppressWarnings("rawtypes") + List l1; + + void m(@SuppressWarnings("rawtypes") List l2) { + @SuppressWarnings("rawtypes") + List l3; + }; +} diff -r 776009a04496 -r bb12ee0dbc91 langtools/test/tools/javap/ListTest.java --- a/langtools/test/tools/javap/ListTest.java Fri Nov 21 08:09:11 2008 -0800 +++ b/langtools/test/tools/javap/ListTest.java Fri Nov 21 15:10:14 2008 -0500 @@ -82,16 +82,16 @@ String[] args = new String[options.size() + 1]; options.toArray(args); args[args.length - 1] = testClassName; - String oldOut = runOldJavap(args); - String newOut = runNewJavap(args); - boolean ok = oldOut.equals(newOut); + byte[] oldOut = runOldJavap(args); + byte[] newOut = runNewJavap(args); + boolean ok = equal(oldOut, newOut); System.err.println((ok ? "pass" : "FAIL") + ": " + testClassName); if (!ok && viewResults) view(oldOut, newOut); return ok; } - String runOldJavap(String[] args) { + byte[] runOldJavap(String[] args) { //System.err.println("OLD: " + Arrays.asList(args)); PrintStream oldOut = System.out; ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -101,29 +101,34 @@ } finally { System.setOut(oldOut); } - return out.toString(); + return out.toByteArray(); } - String runNewJavap(String[] args) { + byte[] runNewJavap(String[] args) { String[] nArgs = new String[args.length + 2]; nArgs[0] = "-XDcompat"; nArgs[1] = "-XDignore.symbol.file"; System.arraycopy(args, 0, nArgs, 2, args.length); //System.err.println("NEW: " + Arrays.asList(nArgs)); - StringWriter out = new StringWriter(); - com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true)); - return out.toString(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + com.sun.tools.javap.Main.run(nArgs, + new PrintWriter(new OutputStreamWriter(out), true)); + return out.toByteArray(); } - File write(String text, String suffix) throws IOException { - File f = File.createTempFile("ListTest", suffix); - FileWriter out = new FileWriter(f); + File write(byte[] text, String suffix) throws IOException { + File f = new File("ListTest." + suffix); + FileOutputStream out = new FileOutputStream(f); out.write(text); out.close(); return f; } - void view(String oldOut, String newOut) throws Exception { + boolean equal(byte[] a1, byte[] a2) { + return Arrays.equals(a1, a2); + } + + void view(byte[] oldOut, byte[] newOut) throws Exception { File oldFile = write(oldOut, "old"); File newFile = write(newOut, "new"); List cmd = new ArrayList();