# HG changeset patch # User amurillo # Date 1421778164 28800 # Node ID 0388b3b63648619e9e79012bb090d4513f2db6f6 # Parent 843229b1db9f1339b3e8164125c38088dff359e1# Parent 6b55dd30a0ba717b14bbb8dd5f36cc1d6cbe5319 Merge diff -r 6b55dd30a0ba -r 0388b3b63648 .hgtags --- a/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 6494b13f88a867026ee316b444d9a4fa589dd6bd jdk9-b43 abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44 bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45 +722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 .hgtags-top-repo --- a/.hgtags-top-repo Thu Jan 15 19:23:49 2015 -0800 +++ b/.hgtags-top-repo Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 02ee8c65622e8bd97496d584e22fc7dcf0edc4ae jdk9-b43 8994f5d87b3bb5e8d317d4e8ccb326da1a73684a jdk9-b44 3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45 +12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 common/autoconf/configure --- a/common/autoconf/configure Thu Jan 15 19:23:49 2015 -0800 +++ b/common/autoconf/configure Tue Jan 20 10:22:44 2015 -0800 @@ -36,6 +36,13 @@ shift fi +if test "x$BASH" = x; then + echo "Error: This script must be run using bash." 1>&2 + exit 1 +fi +# Force autoconf to use bash +export CONFIG_SHELL=$BASH + conf_script_dir="$TOPDIR/common/autoconf" if [ "$CUSTOM_CONFIG_DIR" = "" ]; then diff -r 6b55dd30a0ba -r 0388b3b63648 common/bin/compare.sh --- a/common/bin/compare.sh Thu Jan 15 19:23:49 2015 -0800 +++ b/common/bin/compare.sh Tue Jan 20 10:22:44 2015 -0800 @@ -22,7 +22,7 @@ # questions. # -# This script is processed by configure before it's usable. It is run from +# This script is processed by configure before it's usable. It is run from # the root of the build directory. @@ -76,10 +76,13 @@ TMP=1 if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then + # Filter out date string, ant version and java version differences. TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ - -e '/[<>] Created-By: .* (Oracle Corporation).*/d') + -e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \ + -e '/[<>] [Corpatin]*)/d' \ + -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') fi if test "x$SUFFIX" = "xjava"; then TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ @@ -92,7 +95,7 @@ -e '/\/\/ java GenerateCharacter.*/d') fi # Ignore date strings in class files. - # On Macosx the system sources for generated java classes produce different output on + # On Macosx the system sources for generated java classes produce different output on # consequtive invocations seemingly randomly. # For example a method parameter randomly named "thePoint" or "aPoint". Ignore this. # Anonymous lambda classes get randomly assigned counters in their names. @@ -100,18 +103,18 @@ # To improve performance when large diffs are found, do a rough filtering of classes # elibeble for these exceptions if $GREP -R -e '[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}' \ - -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \ - -e thePoint -e aPoint -e setItemsPtr \ + -e '[0-9]\{2\}/[0-9]\{2\}/[0-9]\{4\}' \ + -e thePoint -e aPoint -e setItemsPtr \ -e 'lambda\$[a-zA-Z0-9]*\$[0-9]' ${THIS_FILE} > /dev/null; then $JAVAP -c -constants -l -p "${OTHER_FILE}" > ${OTHER_FILE}.javap $JAVAP -c -constants -l -p "${THIS_FILE}" > ${THIS_FILE}.javap TMP=$($DIFF ${OTHER_FILE}.javap ${THIS_FILE}.javap | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ - -e '/[0-9]\{2\}\/[0-9]\{2\}\/[0-9]\{4\}/d' \ - -e '/[<>].*Point Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \ - -e '/[<>].*public com\.apple\.jobjc\.Pointer].*public void setItemsPtr(com\.apple\.jobjc\.Pointer].*Point Lcom\/apple\/jobjc\/foundation\/NSPoint;/d' \ + -e '/[<>].*public com\.apple\.jobjc\.Pointer].*public void setItemsPtr(com\.apple\.jobjc\.Pointer].*lambda\$[a-zA-Z0-9]*\$[0-9]*/d') fi fi @@ -121,20 +124,19 @@ # Disable this exception since we aren't changing the properties cleaning method yet. # $CAT $OTHER_FILE | $SED -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \ # | $SED -f "$SRC_ROOT/common/makefiles/support/unicode2x.sed" \ -# | $SED -e '/^#/d' -e '/^$/d' \ +# | $SED -e '/^#/d' -e '/^$/d' \ # -e :a -e '/\\$/N; s/\\\n//; ta' \ -# -e 's/^[ \t]*//;s/[ \t]*$//' \ -# -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned +# -e 's/^[ \t]*//;s/[ \t]*$//' \ +# -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned # Filter out date string differences. TMP=$(LC_ALL=C $DIFF $OTHER_FILE.cleaned $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') fi - if test "x$SUFFIX" = "xMF"; then - # Filter out date string differences. + if test "x$SUFFIX" = "xhtml"; then TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ - $SED -e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d') + $SED -e '/[<>] /d' ) fi if test -n "$TMP"; then echo Files $OTHER_FILE and $THIS_FILE differ @@ -158,7 +160,7 @@ (cd $THIS_DIR && $FIND . -type d | $SORT > $WORK_DIR/dirs_this) $DIFF $WORK_DIR/dirs_other $WORK_DIR/dirs_this > $WORK_DIR/dirs_diff - + echo -n Directory structure... if [ -s $WORK_DIR/dirs_diff ]; then echo Differences found. @@ -192,7 +194,7 @@ (cd $OTHER_DIR && $FIND . ! -type d | $SORT > $WORK_DIR/files_other) (cd $THIS_DIR && $FIND . ! -type d | $SORT > $WORK_DIR/files_this) - + $DIFF $WORK_DIR/files_other $WORK_DIR/files_this > $WORK_DIR/files_diff echo -n File names... @@ -236,11 +238,11 @@ TP=`ls -l ${THIS_DIR}/$f | awk '{printf("%.10s\n", $1);}'` if [ "$OP" != "$TP" ] then - if [ -z "$found" ]; then echo ; found="yes"; fi - $PRINTF "\told: ${OP} new: ${TP}\t$f\n" + if [ -z "$found" ]; then echo ; found="yes"; fi + $PRINTF "\tother: ${OP} this: ${TP}\t$f\n" fi done - if [ -z "$found" ]; then + if [ -z "$found" ]; then echo "Identical!" else REGRESSIONS=true @@ -265,24 +267,22 @@ if [ ! -f ${THIS_DIR}/$f ]; then continue; fi OF=`cd ${OTHER_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` TF=`cd ${THIS_DIR} && $FILE -h $f | $SED 's/BuildID[^,]*//g'` - if [ "$f" = "./src.zip" ] || [[ "$f" = *"/Home/src.zip" ]] || [[ "$f" = *"/lib/JObjC.jar" ]] - then - if [ "`echo $OF | $GREP -ic zip`" -gt 0 -a "`echo $TF | $GREP -ic zip`" -gt 0 ] - then - # the way we produces zip-files make it so that directories are stored in old file - # but not in new (only files with full-path) - # this makes file-5.09 report them as different - continue; - fi - fi - if [ "$OF" != "$TF" ] then - if [ -z "$found" ]; then echo ; found="yes"; fi - $PRINTF "\tother: ${OF}\n\tthis : ${TF}\n" + if [ "`echo $OF | $GREP -c 'Zip archive data'`" -gt 0 ] \ + && [ "`echo $TF | $GREP -c 'Zip archive data'`" -gt 0 ] + then + # the way we produce zip-files make it so that directories are stored in + # old file but not in new (only files with full-path) this makes file + # report them as different + continue + else + if [ -z "$found" ]; then echo ; found="yes"; fi + $PRINTF "\tother: ${OF}\n\tthis : ${TF}\n" + fi fi done - if [ -z "$found" ]; then + if [ -z "$found" ]; then echo "Identical!" else REGRESSIONS=true @@ -296,12 +296,13 @@ THIS_DIR=$1 OTHER_DIR=$2 WORK_DIR=$3 - + GENERAL_FILES=$(cd $THIS_DIR && $FIND . -type f ! -name "*.so" ! -name "*.jar" ! -name "*.zip" \ ! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" ! -name "*.jimage" \ - ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \ + ! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" ! -name "*.cpl" \ ! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \ ! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \ + ! -name "*.obj" ! -name "*.o" ! -name "JavaControlPanelHelper" ! -name "JavaUpdater" \ | $GREP -v "./bin/" | $SORT | $FILTER) echo General files... @@ -377,7 +378,7 @@ THIS_SUFFIX="${THIS_ZIP##*.}" OTHER_SUFFIX="${OTHER_ZIP##*.}" if [ "$THIS_SUFFIX" != "$OTHER_SUFFIX" ]; then - echo The files do not have the same suffix type! + echo "The files do not have the same suffix type! ($THIS_SUFFIX != $OTHER_SUFFIX)" return 2 fi @@ -389,7 +390,7 @@ fi # Not quite identical, the might still contain the same data. # Unpack the jar/zip files in temp dirs - + THIS_UNZIPDIR=$WORK_DIR/$ZIP_FILE.this OTHER_UNZIPDIR=$WORK_DIR/$ZIP_FILE.other $RM -rf $THIS_UNZIPDIR $OTHER_UNZIPDIR @@ -464,9 +465,9 @@ $RM -f $WORK_DIR/$ZIP_FILE.diffs for file in $DIFFING_FILES; do - if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then + if [[ "$ACCEPTED_JARZIP_CONTENTS $EXCEPTIONS" != *"$file"* ]]; then diff_text $OTHER_UNZIPDIR/$file $THIS_UNZIPDIR/$file >> $WORK_DIR/$ZIP_FILE.diffs - fi + fi done if [ -s "$WORK_DIR/$ZIP_FILE.diffs" ]; then @@ -573,6 +574,10 @@ $MKDIR -p $FILE_WORK_DIR + # Make soft links to original files from work dir to facilitate debugging + $LN -f -s $THIS_FILE $WORK_FILE_BASE.this + $LN -f -s $OTHER_FILE $WORK_FILE_BASE.other + ORIG_THIS_FILE="$THIS_FILE" ORIG_OTHER_FILE="$OTHER_FILE" @@ -589,50 +594,51 @@ fi if [ "$OPENJDK_TARGET_OS" = "windows" ]; then - unset _NT_SYMBOL_PATH - # On windows we need to unzip the debug symbols, if present - OTHER_FILE_BASE=${OTHER_FILE/.dll/} - OTHER_FILE_BASE=${OTHER_FILE_BASE/.exe/} - DIZ_NAME=$(basename $OTHER_FILE_BASE).diz + unset _NT_SYMBOL_PATH + # On windows we need to unzip the debug symbols, if present + OTHER_FILE_BASE=${OTHER_FILE/.dll/} + OTHER_FILE_BASE=${OTHER_FILE_BASE/.exe/} + OTHER_FILE_BASE=${OTHER_FILE_BASE/.cpl/} + DIZ_NAME=$(basename $OTHER_FILE_BASE).diz # java.exe and java.dll diz files will have the same name. Have to - # make sure java.exe gets the right one. This is only needed for - # OTHER since in the new build, all pdb files are left around. - if [ "$NAME" = "java.exe" ] && [ -f "$OTHER/tmp/java/java/obj64/java.diz" ]; then - OTHER_DIZ_FILE="$OTHER/tmp/java/java/obj64/java.diz" - elif [ -f "${OTHER_FILE_BASE}.diz" ]; then - OTHER_DIZ_FILE=${OTHER_FILE_BASE}.diz - else + # make sure java.exe gets the right one. This is only needed for + # OTHER since in the new build, all pdb files are left around. + if [ "$NAME" = "java.exe" ] && [ -f "$OTHER/tmp/java/java/obj64/java.diz" ]; then + OTHER_DIZ_FILE="$OTHER/tmp/java/java/obj64/java.diz" + elif [ -f "${OTHER_FILE_BASE}.diz" ]; then + OTHER_DIZ_FILE=${OTHER_FILE_BASE}.diz + else # Some files, jli.dll, appears twice in the image but only one of - # thme has a diz file next to it. - OTHER_DIZ_FILE="$($FIND $OTHER_DIR -name $DIZ_NAME | $SED 1q)" - if [ ! -f "$OTHER_DIZ_FILE" ]; then - # As a last resort, look for diz file in the whole build output - # dir. - OTHER_DIZ_FILE="$($FIND $OTHER -name $DIZ_NAME | $SED 1q)" - fi - fi - if [ -n "$OTHER_DIZ_FILE" ]; then - $MKDIR -p $FILE_WORK_DIR/other - (cd $FILE_WORK_DIR/other ; $UNARCHIVE -o $OTHER_DIZ_FILE) - export _NT_SYMBOL_PATH="$FILE_WORK_DIR/other" - fi - THIS_FILE_BASE=${THIS_FILE/.dll/} - THIS_FILE_BASE=${THIS_FILE_BASE/.exe/} - if [ -f "${THIS_FILE/.dll/}.diz" ]; then - THIS_DIZ_FILE=${THIS_FILE/.dll/}.diz - else - THIS_DIZ_FILE="$($FIND $THIS_DIR -name $DIZ_NAME | $SED 1q)" - if [ ! -f "$THIS_DIZ_FILE" ]; then - # As a last resort, look for diz file in the whole build output - # dir. - THIS_DIZ_FILE="$($FIND $THIS -name $DIZ_NAME | $SED 1q)" - fi - fi - if [ -n "$THIS_DIZ_FILE" ]; then - $MKDIR -p $FILE_WORK_DIR/this - (cd $FILE_WORK_DIR/this ; $UNARCHIVE -o $THIS_DIZ_FILE) - export _NT_SYMBOL_PATH="$_NT_SYMBOL_PATH;$FILE_WORK_DIR/this" - fi + # thme has a diz file next to it. + OTHER_DIZ_FILE="$($FIND $OTHER_DIR -name $DIZ_NAME | $SED 1q)" + if [ ! -f "$OTHER_DIZ_FILE" ]; then + # As a last resort, look for diz file in the whole build output + # dir. + OTHER_DIZ_FILE="$($FIND $OTHER -name $DIZ_NAME | $SED 1q)" + fi + fi + if [ -n "$OTHER_DIZ_FILE" ]; then + $MKDIR -p $FILE_WORK_DIR/other + (cd $FILE_WORK_DIR/other ; $UNARCHIVE -o $OTHER_DIZ_FILE) + export _NT_SYMBOL_PATH="$FILE_WORK_DIR/other" + fi + THIS_FILE_BASE=${THIS_FILE/.dll/} + THIS_FILE_BASE=${THIS_FILE_BASE/.exe/} + if [ -f "${THIS_FILE/.dll/}.diz" ]; then + THIS_DIZ_FILE=${THIS_FILE/.dll/}.diz + else + THIS_DIZ_FILE="$($FIND $THIS_DIR -name $DIZ_NAME | $SED 1q)" + if [ ! -f "$THIS_DIZ_FILE" ]; then + # As a last resort, look for diz file in the whole build output + # dir. + THIS_DIZ_FILE="$($FIND $THIS -name $DIZ_NAME | $SED 1q)" + fi + fi + if [ -n "$THIS_DIZ_FILE" ]; then + $MKDIR -p $FILE_WORK_DIR/this + (cd $FILE_WORK_DIR/this ; $UNARCHIVE -o $THIS_DIZ_FILE) + export _NT_SYMBOL_PATH="$_NT_SYMBOL_PATH;$FILE_WORK_DIR/this" + fi fi if [ -z "$SKIP_BIN_DIFF" ]; then @@ -670,19 +676,19 @@ DIFF_SIZE_REL=$($EXPR $THIS_SIZE \* 100 / $OTHER_SIZE) SIZE_MSG=$($PRINTF "%3d%% %4d" $DIFF_SIZE_REL $DIFF_SIZE_NUM) if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] \ - && [ "$DIFF_SIZE_REL" -lt 102 ]; then + && [ "$DIFF_SIZE_REL" -lt 102 ]; then SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= elif [ "$OPENJDK_TARGET_OS" = "windows" ] \ - && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ - && [ "$DIFF_SIZE_NUM" = 512 ]; then - # On windows, size of binaries increase in 512 increments. + && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ + && [ "$DIFF_SIZE_NUM" = 512 ]; then + # On windows, size of binaries increase in 512 increments. SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= elif [ "$OPENJDK_TARGET_OS" = "windows" ] \ - && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ - && [ "$DIFF_SIZE_NUM" = -512 ]; then - # On windows, size of binaries increase in 512 increments. + && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \ + && [ "$DIFF_SIZE_NUM" = -512 ]; then + # On windows, size of binaries increase in 512 increments. SIZE_MSG="($SIZE_MSG)" DIFF_SIZE= else @@ -717,18 +723,18 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then # The output from dumpbin on windows differs depending on if the debug symbol # files are still around at the location the binary is pointing too. Need - # to filter out that extra information. - $DUMPBIN -exports $OTHER_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $DUMPBIN -exports $THIS_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + # to filter out that extra information. + $DUMPBIN -exports $OTHER_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $DUMPBIN -exports $THIS_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this elif [ "$OPENJDK_TARGET_OS" = "solaris" ]; then # Some symbols get seemingly random 15 character prefixes. Filter them out. $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this else - $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other - $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this fi - + LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff if [ -s $WORK_FILE_BASE.symbols.diff ]; then SYM_MSG=" diff " @@ -741,7 +747,7 @@ SYM_MSG=" $SYM_MSG " fi else - SYM_MSG="($SYM_MSG)" + SYM_MSG="($SYM_MSG)" DIFF_SYM= fi else @@ -754,48 +760,48 @@ # Check dependencies if [ -n "$LDD_CMD" ]; then - (cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME 2>/dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq) - (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2 $WORK_FILE_BASE.deps.this.uniq) - (cd $FILE_WORK_DIR && $RM -f $NAME) - - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff - LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq - - if [ -s $WORK_FILE_BASE.deps.diff ]; then + (cd $FILE_WORK_DIR && $CP $OTHER_FILE . && $LDD_CMD $NAME 2>/dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.other | $UNIQ > $WORK_FILE_BASE.deps.other.uniq) + (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2 $WORK_FILE_BASE.deps.this.uniq) + (cd $FILE_WORK_DIR && $RM -f $NAME) + + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq + + if [ -s $WORK_FILE_BASE.deps.diff ]; then if [ -s $WORK_FILE_BASE.deps.diff.uniq ]; then - DEP_MSG=" diff " + DEP_MSG=" diff " else - DEP_MSG=" redun " + DEP_MSG=" redun " fi if [[ "$ACCEPTED_DEP_DIFF" != *"$BIN_FILE"* ]]; then - DIFF_DEP=true - if [[ "$KNOWN_DEP_DIFF" != *"$BIN_FILE"* ]]; then + DIFF_DEP=true + if [[ "$KNOWN_DEP_DIFF" != *"$BIN_FILE"* ]]; then DEP_MSG="*$DEP_MSG*" REGRESSIONS=true - else + else DEP_MSG=" $DEP_MSG " - fi + fi else - DEP_MSG="($DEP_MSG)" - DIFF_DEP= + DEP_MSG="($DEP_MSG)" + DIFF_DEP= fi - else - DEP_MSG=" " - DIFF_DEP= + else + DEP_MSG=" " + DIFF_DEP= if [[ "$KNOWN_DEP_DIFF $ACCEPTED_DEP_DIFF" = *"$BIN_FILE"* ]]; then DEP_MSG=" ! " fi - fi + fi else - DEP_MSG=" - " + DEP_MSG=" - " fi - + # Compare fulldump output if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then $FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1 $FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1 LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff - + if [ -s $WORK_FILE_BASE.fulldump.diff ]; then ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}') ELF_MSG=$($PRINTF "%8d" $ELF_DIFF_SIZE) @@ -822,14 +828,17 @@ # Compare disassemble output if [ -n "$DIS_CMD" ] && [ -z "$SKIP_DIS_DIFF" ]; then - if [ -z "$DIS_DIFF_FILTER" ]; then - DIS_DIFF_FILTER="$CAT" - fi - $DIS_CMD $OTHER_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.other 2>&1 - $DIS_CMD $THIS_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.this 2>&1 - + # By default we filter out differences that include references to symbols. + # To get a raw diff with the complete disassembly, set + # DIS_DIFF_FILTER="$CAT" + if [ -z "$DIS_DIFF_FILTER" ]; then + DIS_DIFF_FILTER="$GREP -v ' # .* <.*>$'" + fi + $DIS_CMD $OTHER_FILE | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.other 2>&1 + $DIS_CMD $THIS_FILE | $GREP -v $NAME | eval "$DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 + LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff - + if [ -s $WORK_FILE_BASE.dis.diff ]; then DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}') DIS_MSG=$($PRINTF "%8d" $DIS_DIFF_SIZE) @@ -907,7 +916,9 @@ OTHER_DIR=$2 WORK_DIR=$3 - LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' -o -name 'JavaControlPanel' \) | $SORT | $FILTER) + LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' \ + -o -name '*.dll' -o -name '*.obj' -o -name '*.o' \ + -o -name '*.cpl' \) | $SORT | $FILTER) if [ -n "$LIBS" ]; then echo Libraries... @@ -967,7 +978,7 @@ $MKDIR -p $COMPARE_ROOT if [ "$OPENJDK_TARGET_OS" = "windows" ]; then if [ "$(uname -o)" = "Cygwin" ]; then - COMPARE_ROOT=$(cygpath -msa $COMPARE_ROOT) + COMPARE_ROOT=$(cygpath -msa $COMPARE_ROOT) fi fi @@ -1091,7 +1102,7 @@ CMP_JARS=true CMP_LIBS=true CMP_EXECS=true - + if [ -z "$FILTER" ]; then FILTER="$GREP" fi @@ -1177,8 +1188,8 @@ OTHER_J2RE="$OTHER/images/jre" echo "Selecting jdk images for compare" else - echo "No common images found." - exit 1 + echo "No common images found." + exit 1 fi if [ -d "$THIS/images/jdk-bundle" ] && [ -d "$OTHER/images/jdk-bundle" ]; then @@ -1189,6 +1200,17 @@ echo "Also comparing macosx bundles" fi + if [ -d "$THIS/deploy" ] && [ -d "$OTHER/deploy" ]; then + THIS_DEPLOY_BUNDLE_DIR="$THIS/deploy/dist/installer/bundles" + OTHER_DEPLOY_BUNDLE_DIR="$OTHER/deploy/bundles" + echo "Also comparing deploy/bundles" + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then + THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/JavaAppletPlugin.plugin" + OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/JavaAppletPlugin.plugin" + echo "Also comparing JavaAppletPlugin" + fi + fi + if [ -d "$OTHER/images" ]; then OTHER_SEC_DIR="$OTHER/images" else @@ -1212,7 +1234,7 @@ if [ -d "$THIS/docs" ] && [ -d "$OTHER/docs" ]; then THIS_DOCS="$THIS/docs" OTHER_DOCS="$OTHER/docs" - echo "Also comparing docs" + echo "Also comparing docs" else echo "WARNING! Docs haven't been built and won't be compared." fi @@ -1227,7 +1249,7 @@ compare_dirs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk echo -n "J2RE " compare_dirs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re - + echo -n "J2SDK " compare_files $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk echo -n "J2RE " @@ -1238,7 +1260,7 @@ compare_dirs $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle echo -n "J2RE Bundle " compare_dirs $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/jre-bundle - + echo -n "J2SDK Bundle " compare_files $THIS_J2SDK_BUNDLE $OTHER_J2SDK_BUNDLE $COMPARE_ROOT/jdk-bundle echo -n "J2RE Bundle " @@ -1254,6 +1276,12 @@ compare_dirs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir compare_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_dirs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + echo -n "JavaAppletPlugin " + compare_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_PERMS" = "true" ]; then @@ -1266,6 +1294,10 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_permissions $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_permissions $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_TYPES" = "true" ]; then @@ -1284,6 +1316,10 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_file_types $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_file_types $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_GENERAL" = "true" ]; then @@ -1306,6 +1342,10 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_general_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_general_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_ZIPS" = "true" ]; then @@ -1333,6 +1373,12 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_zip_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_BUNDLE_DIR" ] && [ -n "$OTHER_DEPLOY_BUNDLE_DIR" ]; then + compare_all_zip_files $THIS_DEPLOY_BUNDLE_DIR $OTHER_DEPLOY_BUNDLE_DIR $COMPARE_ROOT/deploy-bundle + fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + compare_all_zip_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_JARS" = "true" ]; then @@ -1342,6 +1388,9 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_jar_files $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + compare_all_jar_files $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_LIBS" = "true" ]; then @@ -1356,15 +1405,27 @@ if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_libs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_all_libs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi if [ "$CMP_EXECS" = "true" ]; then if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then compare_all_execs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk + if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then + echo -n "J2RE " + compare_all_execs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re + fi fi if [ -n "$THIS_BASE_DIR" ] && [ -n "$OTHER_BASE_DIR" ]; then compare_all_execs $THIS_BASE_DIR $OTHER_BASE_DIR $COMPARE_ROOT/base_dir fi + if [ -n "$THIS_DEPLOY_APPLET_PLUGIN_DIR" ] && [ -n "$OTHER_DEPLOY_APPLET_PLUGIN_DIR" ]; then + echo -n "JavaAppletPlugin " + compare_all_execs $THIS_DEPLOY_APPLET_PLUGIN_DIR $OTHER_DEPLOY_APPLET_PLUGIN_DIR $COMPARE_ROOT/plugin + fi fi echo diff -r 6b55dd30a0ba -r 0388b3b63648 corba/.hgtags --- a/corba/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/corba/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 9645e35616b60c5c07b4fdf11a132afc8081dfa8 jdk9-b43 1f57bd728c9e6865ccb9d43ccd80a1c11230a32f jdk9-b44 9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45 +326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/.hgtags --- a/hotspot/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -448,3 +448,4 @@ 65a9747147b8090037541040ba67156ec914db6a jdk9-b43 43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44 5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45 +a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/make/Makefile --- a/hotspot/agent/make/Makefile Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/make/Makefile Tue Jan 20 10:22:44 2015 -0800 @@ -58,15 +58,19 @@ sun.jvm.hotspot.debugger.dummy \ sun.jvm.hotspot.debugger.linux \ sun.jvm.hotspot.debugger.linux.amd64 \ +sun.jvm.hotspot.debugger.linux.ppc64 \ sun.jvm.hotspot.debugger.linux.x86 \ sun.jvm.hotspot.debugger.posix \ sun.jvm.hotspot.debugger.posix.elf \ +sun.jvm.hotspot.debugger.ppc64 \ sun.jvm.hotspot.debugger.proc \ sun.jvm.hotspot.debugger.proc.amd64 \ +sun.jvm.hotspot.debugger.proc.ppc64 \ sun.jvm.hotspot.debugger.proc.sparc \ sun.jvm.hotspot.debugger.proc.x86 \ sun.jvm.hotspot.debugger.remote \ sun.jvm.hotspot.debugger.remote.amd64 \ +sun.jvm.hotspot.debugger.remote.ppc64 \ sun.jvm.hotspot.debugger.remote.sparc \ sun.jvm.hotspot.debugger.remote.x86 \ sun.jvm.hotspot.debugger.sparc \ @@ -93,9 +97,11 @@ sun.jvm.hotspot.runtime.bsd_x86 \ sun.jvm.hotspot.runtime.linux \ sun.jvm.hotspot.runtime.linux_amd64 \ +sun.jvm.hotspot.runtime.linux_ppc64 \ sun.jvm.hotspot.runtime.linux_sparc \ sun.jvm.hotspot.runtime.linux_x86 \ sun.jvm.hotspot.runtime.posix \ +sun.jvm.hotspot.runtime.ppc64 \ sun.jvm.hotspot.runtime.solaris_amd64 \ sun.jvm.hotspot.runtime.solaris_sparc \ sun.jvm.hotspot.runtime.solaris_x86 \ @@ -142,15 +148,19 @@ sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \ sun/jvm/hotspot/debugger/dummy/*.java \ sun/jvm/hotspot/debugger/linux/*.java \ +sun/jvm/hotspot/debugger/linux/ppc64/*.java \ sun/jvm/hotspot/debugger/linux/x86/*.java \ sun/jvm/hotspot/debugger/posix/*.java \ sun/jvm/hotspot/debugger/posix/elf/*.java \ +sun/jvm/hotspot/debugger/ppc64/*.java \ sun/jvm/hotspot/debugger/proc/*.java \ sun/jvm/hotspot/debugger/proc/amd64/*.java \ +sun/jvm/hotspot/debugger/proc/ppc64/*.java \ sun/jvm/hotspot/debugger/proc/sparc/*.java \ sun/jvm/hotspot/debugger/proc/x86/*.java \ sun/jvm/hotspot/debugger/remote/*.java \ sun/jvm/hotspot/debugger/remote/amd64/*.java \ +sun/jvm/hotspot/debugger/remote/ppc64/*.java \ sun/jvm/hotspot/debugger/remote/sparc/*.java \ sun/jvm/hotspot/debugger/remote/x86/*.java \ sun/jvm/hotspot/debugger/sparc/*.java \ @@ -174,9 +184,11 @@ sun/jvm/hotspot/runtime/bsd_x86/*.java \ sun/jvm/hotspot/runtime/linux/*.java \ sun/jvm/hotspot/runtime/linux_amd64/*.java \ +sun/jvm/hotspot/runtime/linux_ppc64/*.java \ sun/jvm/hotspot/runtime/linux_sparc/*.java \ sun/jvm/hotspot/runtime/linux_x86/*.java \ sun/jvm/hotspot/runtime/posix/*.java \ +sun/jvm/hotspot/runtime/ppc64/*.java \ sun/jvm/hotspot/runtime/solaris_amd64/*.java \ sun/jvm/hotspot/runtime/solaris_sparc/*.java \ sun/jvm/hotspot/runtime/solaris_x86/*.java \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/os/linux/LinuxDebuggerLocal.c --- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Tue Jan 20 10:22:44 2015 -0800 @@ -49,6 +49,10 @@ #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h" #endif +#ifdef ppc64 +#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h" +#endif + static jfieldID p_ps_prochandle_ID = 0; static jfieldID threadList_ID = 0; static jfieldID loadObjectList_ID = 0; @@ -341,7 +345,7 @@ return (err == PS_OK)? array : 0; } -#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) +#if defined(i386) || defined(amd64) || defined(sparc) || defined(sparcv9) | defined(ppc64) JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0 (JNIEnv *env, jobject this_obj, jint lwp_id) { @@ -366,6 +370,10 @@ #if defined(sparc) || defined(sparcv9) #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG #endif +#ifdef ppc64 +#define NPRGREG sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_NPRGREG +#endif + array = (*env)->NewLongArray(env, NPRGREG); CHECK_EXCEPTION_(0); @@ -458,6 +466,45 @@ regs[REG_INDEX(R_O7)] = gregs.u_regs[14]; #endif /* sparc */ +#ifdef ppc64 +#define REG_INDEX(reg) sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext_##reg + + regs[REG_INDEX(LR)] = gregs.link; + regs[REG_INDEX(NIP)] = gregs.nip; + regs[REG_INDEX(R0)] = gregs.gpr[0]; + regs[REG_INDEX(R1)] = gregs.gpr[1]; + regs[REG_INDEX(R2)] = gregs.gpr[2]; + regs[REG_INDEX(R3)] = gregs.gpr[3]; + regs[REG_INDEX(R4)] = gregs.gpr[4]; + regs[REG_INDEX(R5)] = gregs.gpr[5]; + regs[REG_INDEX(R6)] = gregs.gpr[6]; + regs[REG_INDEX(R7)] = gregs.gpr[7]; + regs[REG_INDEX(R8)] = gregs.gpr[8]; + regs[REG_INDEX(R9)] = gregs.gpr[9]; + regs[REG_INDEX(R10)] = gregs.gpr[10]; + regs[REG_INDEX(R11)] = gregs.gpr[11]; + regs[REG_INDEX(R12)] = gregs.gpr[12]; + regs[REG_INDEX(R13)] = gregs.gpr[13]; + regs[REG_INDEX(R14)] = gregs.gpr[14]; + regs[REG_INDEX(R15)] = gregs.gpr[15]; + regs[REG_INDEX(R16)] = gregs.gpr[16]; + regs[REG_INDEX(R17)] = gregs.gpr[17]; + regs[REG_INDEX(R18)] = gregs.gpr[18]; + regs[REG_INDEX(R19)] = gregs.gpr[19]; + regs[REG_INDEX(R20)] = gregs.gpr[20]; + regs[REG_INDEX(R21)] = gregs.gpr[21]; + regs[REG_INDEX(R22)] = gregs.gpr[22]; + regs[REG_INDEX(R23)] = gregs.gpr[23]; + regs[REG_INDEX(R24)] = gregs.gpr[24]; + regs[REG_INDEX(R25)] = gregs.gpr[25]; + regs[REG_INDEX(R26)] = gregs.gpr[26]; + regs[REG_INDEX(R27)] = gregs.gpr[27]; + regs[REG_INDEX(R28)] = gregs.gpr[28]; + regs[REG_INDEX(R29)] = gregs.gpr[29]; + regs[REG_INDEX(R30)] = gregs.gpr[30]; + regs[REG_INDEX(R31)] = gregs.gpr[31]; + +#endif (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); return array; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/os/linux/symtab.c --- a/hotspot/agent/src/os/linux/symtab.c Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/os/linux/symtab.c Tue Jan 20 10:22:44 2015 -0800 @@ -325,6 +325,12 @@ // Reading of elf header struct elf_section *scn_cache = NULL; +#if defined(ppc64) && !defined(ABI_ELFv2) + // Only big endian ppc64 (i.e. ABI_ELFv1) has 'official procedure descriptors' in ELF files + // see: http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html + struct elf_section *opd_sect = NULL; + ELF_SHDR *opd = NULL; +#endif int cnt = 0; ELF_SHDR* shbuf = NULL; ELF_SHDR* cursct = NULL; @@ -368,6 +374,14 @@ cursct++; } +#if defined(ppc64) && !defined(ABI_ELFv2) + opd_sect = find_section_by_name(".opd", fd, &ehdr, scn_cache); + if (opd_sect != NULL && opd_sect->c_data != NULL && opd_sect->c_shdr != NULL) { + // plausibility check + opd = opd_sect->c_shdr; + } +#endif + for (cnt = 1; cnt < ehdr.e_shnum; cnt++) { ELF_SHDR *shdr = scn_cache[cnt].c_shdr; @@ -412,6 +426,7 @@ // copy symbols info our symtab and enter them info the hash table for (j = 0; j < n; j++, syms++) { ENTRY item, *ret; + uintptr_t sym_value; char *sym_name = symtab->strs + syms->st_name; // skip non-object and non-function symbols @@ -422,9 +437,19 @@ if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue; symtab->symbols[j].name = sym_name; - symtab->symbols[j].offset = syms->st_value - baseaddr; symtab->symbols[j].size = syms->st_size; + sym_value = syms->st_value; +#if defined(ppc64) && !defined(ABI_ELFv2) + // see hotspot/src/share/vm/utilities/elfFuncDescTable.hpp for a detailed description + // of why we have to go this extra way via the '.opd' section on big endian ppc64 + if (opd != NULL && *sym_name != '.' && + (opd->sh_addr <= sym_value && sym_value <= opd->sh_addr + opd->sh_size)) { + sym_value = ((ELF_ADDR*)opd_sect->c_data)[(sym_value - opd->sh_addr) / sizeof(ELF_ADDR*)]; + } +#endif + + symtab->symbols[j].offset = sym_value - baseaddr; item.key = sym_name; item.data = (void *)&(symtab->symbols[j]); @@ -433,9 +458,17 @@ } } +#if defined(ppc64) && !defined(ABI_ELFv2) + // On Linux/PPC64 the debuginfo files contain an empty function descriptor + // section (i.e. '.opd' section) which makes the resolution of symbols + // with the above algorithm impossible (we would need the have both, the + // .opd section from the library and the symbol table from the debuginfo + // file which doesn't match with the current workflow.) + goto quit; +#endif + // Look for a separate debuginfo file. if (try_debuginfo) { - // We prefer a debug symtab to an object's own symtab, so look in // the debuginfo file. We stash a copy of the old symtab in case // there is no debuginfo. diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Tue Jan 20 10:22:44 2015 -0800 @@ -34,6 +34,6 @@ } public boolean isBigEndian() { - return true; + return "big".equals(System.getProperty("sun.cpu.endian")); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Tue Jan 20 10:22:44 2015 -0800 @@ -26,14 +26,17 @@ import java.io.*; import java.util.*; + import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.x86.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.sparc.*; +import sun.jvm.hotspot.debugger.ppc64.*; import sun.jvm.hotspot.debugger.linux.x86.*; import sun.jvm.hotspot.debugger.linux.amd64.*; import sun.jvm.hotspot.debugger.linux.sparc.*; +import sun.jvm.hotspot.debugger.linux.ppc64.*; import sun.jvm.hotspot.utilities.*; class LinuxCDebugger implements CDebugger { @@ -96,7 +99,14 @@ Address pc = context.getRegisterAsAddress(SPARCThreadContext.R_O7); if (pc == null) return null; return new LinuxSPARCCFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize()); - } else { + } else if (cpu.equals("ppc64")) { + PPC64ThreadContext context = (PPC64ThreadContext) thread.getContext(); + Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); + if (sp == null) return null; + Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC); + if (pc == null) return null; + return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize()); + } else { // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu ThreadContext context = (ThreadContext) thread.getContext(); return context.getTopFrame(dbg); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Tue Jan 20 10:22:44 2015 -0800 @@ -29,6 +29,7 @@ import sun.jvm.hotspot.debugger.linux.amd64.*; import sun.jvm.hotspot.debugger.linux.ia64.*; import sun.jvm.hotspot.debugger.linux.x86.*; +import sun.jvm.hotspot.debugger.linux.ppc64.*; import sun.jvm.hotspot.debugger.linux.sparc.*; class LinuxThreadContextFactory { @@ -42,6 +43,8 @@ return new LinuxIA64ThreadContext(dbg); } else if (cpu.equals("sparc")) { return new LinuxSPARCThreadContext(dbg); + } else if (cpu.equals("ppc64")) { + return new LinuxPPC64ThreadContext(dbg); } else { try { Class tcc = Class.forName("sun.jvm.hotspot.debugger.linux." + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.linux.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.linux.*; +import sun.jvm.hotspot.debugger.cdbg.*; +import sun.jvm.hotspot.debugger.cdbg.basic.*; + +final public class LinuxPPC64CFrame extends BasicCFrame { + // package/class internals only + + public LinuxPPC64CFrame(LinuxDebugger dbg, Address sp, Address pc, int address_size) { + super(dbg.getCDebugger()); + this.sp = sp; + this.pc = pc; + this.dbg = dbg; + this.address_size = address_size; + } + + // override base class impl to avoid ELF parsing + public ClosestSymbol closestSymbolToPC() { + // try native lookup in debugger. + return dbg.lookup(dbg.getAddressValue(pc())); + } + + public Address pc() { + return pc; + } + + public Address localVariableBase() { + return sp; + } + + public CFrame sender(ThreadProxy thread) { + if (sp == null) { + return null; + } + + Address nextSP = sp.getAddressAt(0); + if (nextSP == null) { + return null; + } + Address nextPC = sp.getAddressAt(2 * address_size); + if (nextPC == null) { + return null; + } + return new LinuxPPC64CFrame(dbg, nextSP, nextPC, address_size); + } + + public static int PPC64_STACK_BIAS = 0; + private static int address_size; + private Address pc; + private Address sp; + private LinuxDebugger dbg; +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.linux.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.linux.*; + +public class LinuxPPC64ThreadContext extends PPC64ThreadContext { + private LinuxDebugger debugger; + + public LinuxPPC64ThreadContext(LinuxDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.cdbg.*; + +/** Specifies the thread context on ppc64 platforms; only a sub-portion + * of the context is guaranteed to be present on all operating + * systems. */ + +public abstract class PPC64ThreadContext implements ThreadContext { + + // NOTE: The indices for the various registers must be maintained as + // listed across various operating systems. However, only a small + // subset of the registers' values are guaranteed to be present (and + // must be present for the SA's stack walking to work). + + public static final int R31 = 0; + public static final int R30 = 1; + public static final int R29 = 2; + public static final int R28 = 3; + public static final int R27 = 4; + public static final int R26 = 5; + public static final int R25 = 6; + public static final int R24 = 7; + public static final int R23 = 8; + public static final int R22 = 9; + public static final int R21 = 10; + public static final int R20 = 11; + public static final int R19 = 12; + public static final int R18 = 13; + public static final int R17 = 14; + public static final int R16 = 15; + public static final int R15 = 16; + public static final int R14 = 17; + public static final int R13 = 18; + public static final int R12 = 19; + public static final int R11 = 20; + public static final int R10 = 21; + public static final int R9 = 22; + public static final int R8 = 23; + public static final int R7 = 24; + public static final int R6 = 25; + public static final int R5 = 26; + public static final int R4 = 27; + public static final int R3 = 28; + public static final int R2 = 29; + public static final int R1 = 30; + public static final int R0 = 31; + public static final int NIP = 32; + public static final int LR = 33; + + public static final int NPRGREG = 34; + + private static final String[] regNames = { + "r31", "r30", "r29", "r28", "r27", "r26", "r25", "r24", + "r23", "r22", "r21", "r20", "r19", "r18", "r17", "r16", + "r15", "r14", "r13", "r12", "r11", "r10", "r9", "r8", + "r7", "r6", "r5", "r4", "r3", "r2", "r1", "r0", + "nip", "link" + }; + + public static final int PC = NIP; + public static final int SP = R1; + + private long[] data; + + public PPC64ThreadContext() { + data = new long[NPRGREG]; + } + + public int getNumRegisters() { + return NPRGREG; + } + + public String getRegisterName(int index) { + return regNames[index]; + } + + public void setRegister(int index, long value) { + data[index] = value; + } + + public long getRegister(int index) { + return data[index]; + } + + public CFrame getTopFrame(Debugger dbg) { + return null; + } + + /** This can't be implemented in this class since we would have to + * tie the implementation to, for example, the debugging system */ + public abstract void setRegisterAsAddress(int index, Address value); + + /** This can't be implemented in this class since we would have to + * tie the implementation to, for example, the debugging system */ + public abstract Address getRegisterAsAddress(int index); + +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,9 @@ import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.debugger.proc.amd64.*; import sun.jvm.hotspot.debugger.proc.sparc.*; +import sun.jvm.hotspot.debugger.proc.ppc64.*; import sun.jvm.hotspot.debugger.proc.x86.*; +import sun.jvm.hotspot.debugger.ppc64.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.sparc.*; import sun.jvm.hotspot.debugger.x86.*; @@ -86,6 +88,10 @@ threadFactory = new ProcAMD64ThreadFactory(this); pcRegIndex = AMD64ThreadContext.RIP; fpRegIndex = AMD64ThreadContext.RBP; + } else if (cpu.equals("ppc64")) { + threadFactory = new ProcPPC64ThreadFactory(this); + pcRegIndex = PPC64ThreadContext.PC; + fpRegIndex = PPC64ThreadContext.SP; } else { try { Class tfc = Class.forName("sun.jvm.hotspot.debugger.proc." + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.proc.*; +import sun.jvm.hotspot.utilities.*; + +public class ProcPPC64Thread implements ThreadProxy { + private ProcDebugger debugger; + private int id; + + public ProcPPC64Thread(ProcDebugger debugger, Address addr) { + this.debugger = debugger; + + // FIXME: the size here should be configurable. However, making it + // so would produce a dependency on the "types" package from the + // debugger package, which is not desired. + this.id = (int) addr.getCIntegerAt(0, 4, true); + } + + public ProcPPC64Thread(ProcDebugger debugger, long id) { + this.debugger = debugger; + this.id = (int) id; + } + + public ThreadContext getContext() throws IllegalThreadStateException { + ProcPPC64ThreadContext context = new ProcPPC64ThreadContext(debugger); + long[] regs = debugger.getThreadIntegerRegisterSet(id); + if (Assert.ASSERTS_ENABLED) { + Assert.that(regs.length <= PPC64ThreadContext.NPRGREG, "size of register set is greater than " + PPC64ThreadContext.NPRGREG); + } + for (int i = 0; i < regs.length; i++) { + context.setRegister(i, regs[i]); + } + return context; + } + + public boolean canSetContext() throws DebuggerException { + return false; + } + + public void setContext(ThreadContext context) + throws IllegalThreadStateException, DebuggerException { + throw new DebuggerException("Unimplemented"); + } + + public String toString() { + return "t@" + id; + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof ProcPPC64Thread)) { + return false; + } + + return (((ProcPPC64Thread) obj).id == id); + } + + public int hashCode() { + return id; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.proc.*; + +public class ProcPPC64ThreadContext extends PPC64ThreadContext { + private ProcDebugger debugger; + + public ProcPPC64ThreadContext(ProcDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.proc.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.proc.*; + +public class ProcPPC64ThreadFactory implements ProcThreadFactory { + private ProcDebugger debugger; + + public ProcPPC64ThreadFactory(ProcDebugger debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new ProcPPC64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new ProcPPC64Thread(debugger, id); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Tue Jan 20 10:22:44 2015 -0800 @@ -33,6 +33,7 @@ import sun.jvm.hotspot.debugger.remote.sparc.*; import sun.jvm.hotspot.debugger.remote.x86.*; import sun.jvm.hotspot.debugger.remote.amd64.*; +import sun.jvm.hotspot.debugger.remote.ppc64.*; /** An implementation of Debugger which wraps a RemoteDebugger, providing remote debugging via RMI. @@ -70,6 +71,11 @@ cachePageSize = 4096; cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); unalignedAccessesOkay = true; + } else if (cpu.equals("ppc64")) { + threadFactory = new RemotePPC64ThreadFactory(this); + cachePageSize = 4096; + cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize); + unalignedAccessesOkay = true; } else { try { Class tf = Class.forName("sun.jvm.hotspot.debugger.remote." + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.remote.*; +import sun.jvm.hotspot.utilities.*; + +public class RemotePPC64Thread extends RemoteThread { + public RemotePPC64Thread(RemoteDebuggerClient debugger, Address addr) { + super(debugger, addr); + } + + public RemotePPC64Thread(RemoteDebuggerClient debugger, long id) { + super(debugger, id); + } + + public ThreadContext getContext() throws IllegalThreadStateException { + RemotePPC64ThreadContext context = new RemotePPC64ThreadContext(debugger); + long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) : + debugger.getThreadIntegerRegisterSet(id); + if (Assert.ASSERTS_ENABLED) { + Assert.that(regs.length == PPC64ThreadContext.NPRGREG, "size of register set must match"); + } + for (int i = 0; i < regs.length; i++) { + context.setRegister(i, regs[i]); + } + return context; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.debugger.remote.*; + +public class RemotePPC64ThreadContext extends PPC64ThreadContext { + private RemoteDebuggerClient debugger; + + public RemotePPC64ThreadContext(RemoteDebuggerClient debugger) { + super(); + this.debugger = debugger; + } + + /** This can't be implemented in this class since we would have to + tie the implementation to, for example, the debugging system */ + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + /** This can't be implemented in this class since we would have to + tie the implementation to, for example, the debugging system */ + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.remote.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.remote.*; + +public class RemotePPC64ThreadFactory implements RemoteThreadFactory { + private RemoteDebuggerClient debugger; + + public RemotePPC64ThreadFactory(RemoteDebuggerClient debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new RemotePPC64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new RemotePPC64Thread(debugger, id); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Tue Jan 20 10:22:44 2015 -0800 @@ -25,6 +25,7 @@ package sun.jvm.hotspot.runtime; import java.util.*; + import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.types.*; import sun.jvm.hotspot.runtime.solaris_sparc.SolarisSPARCJavaThreadPDAccess; @@ -34,6 +35,7 @@ import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess; @@ -87,6 +89,8 @@ access = new LinuxAMD64JavaThreadPDAccess(); } else if (cpu.equals("sparc")) { access = new LinuxSPARCJavaThreadPDAccess(); + } else if (cpu.equals("ppc64")) { + access = new LinuxPPC64JavaThreadPDAccess(); } else { try { access = (JavaThreadPDAccess) diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java Tue Jan 20 10:22:44 2015 -0800 @@ -78,7 +78,7 @@ } if (f.isRuntimeFrame()) { - // This is a conversion frame. Skip this frame and try again. + // This is a conversion frame or a Stub routine. Skip this frame and try again. RegisterMap tempMap = regMap.copy(); Frame s = f.sender(tempMap); return newVFrame(s, tempMap, thread, unsafe, false); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.linux_ppc64; + +import java.io.*; +import java.util.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.ppc64.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +public class LinuxPPC64JavaThreadPDAccess implements JavaThreadPDAccess { + private static AddressField osThreadField; + + // Field from OSThread + private static CIntegerField osThreadThreadIDField; + + // This is currently unneeded but is being kept in case we change + // the currentFrameGuess algorithm + private static final long GUESS_SCAN_RANGE = 128 * 1024; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("JavaThread"); + osThreadField = type.getAddressField("_osthread"); + + Type osThreadType = db.lookupType("OSThread"); + osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id"); + } + + public Address getLastJavaFP(Address addr) { + return null; + } + + public Address getLastJavaPC(Address addr) { + return null; + } + + public Address getBaseOfStackPointer(Address addr) { + return null; + } + + public Frame getLastFramePD(JavaThread thread, Address addr) { + Address fp = thread.getLastJavaFP(); + if (fp == null) { + return null; // no information + } + return new PPC64Frame(thread.getLastJavaSP(), fp); + } + + public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { + return new PPC64RegisterMap(thread, updateMap); + } + + public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + ThreadProxy t = getThreadProxy(addr); + PPC64ThreadContext context = (PPC64ThreadContext) t.getContext(); + PPC64CurrentFrameGuess guesser = new PPC64CurrentFrameGuess(context, thread); + if (!guesser.run(GUESS_SCAN_RANGE)) { + return null; + } + if (guesser.getPC() == null) { + return new PPC64Frame(guesser.getSP(), guesser.getFP()); + } else { + return new PPC64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); + } + } + + public void printThreadIDOn(Address addr, PrintStream tty) { + tty.print(getThreadProxy(addr)); + } + + public void printInfoOn(Address threadAddr, PrintStream tty) { + tty.print("Thread id: "); + printThreadIDOn(threadAddr, tty); + // tty.println("\nPostJavaState: " + getPostJavaState(threadAddr)); + } + + public Address getLastSP(Address addr) { + ThreadProxy t = getThreadProxy(addr); + PPC64ThreadContext context = (PPC64ThreadContext) t.getContext(); + return context.getRegisterAsAddress(PPC64ThreadContext.SP); + } + + public Address getLastFP(Address addr) { + return getLastSP(addr).getAddressAt(0); + } + + public ThreadProxy getThreadProxy(Address addr) { + // Addr is the address of the JavaThread. + // Fetch the OSThread (for now and for simplicity, not making a + // separate "OSThread" class in this package) + Address osThreadAddr = osThreadField.getValue(addr); + // Get the address of the _thread_id from the OSThread + Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + + JVMDebugger debugger = VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.ppc64.*; +import sun.jvm.hotspot.code.*; +import sun.jvm.hotspot.interpreter.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.ppc64.*; + +/**

Should be able to be used on all ppc64 platforms we support + (Linux/ppc64) to implement JavaThread's "currentFrameGuess()" + functionality. Input is a PPC64ThreadContext; output is SP, FP, + and PC for an PPC64Frame. Instantiation of the PPC64Frame is left + to the caller, since we may need to subclass PPC64Frame to support + signal handler frames on Unix platforms.

+ */ + +public class PPC64CurrentFrameGuess { + private PPC64ThreadContext context; + private JavaThread thread; + private Address spFound; + private Address fpFound; + private Address pcFound; + + private static final boolean DEBUG; + static { + DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null; + } + + public PPC64CurrentFrameGuess(PPC64ThreadContext context, + JavaThread thread) { + this.context = context; + this.thread = thread; + } + + /** Returns false if not able to find a frame within a reasonable range. */ + public boolean run(long regionInBytesToSearch) { + Address sp = context.getRegisterAsAddress(PPC64ThreadContext.SP); + Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC); + if (sp == null) { + // Bail out if no last java frame either + if (thread.getLastJavaSP() != null) { + Address javaSP = thread.getLastJavaSP(); + Address javaFP = javaSP.getAddressAt(0); + setValues(javaSP, javaFP, null); + return true; + } + return false; + } + /* There is no frame pointer per se for the ppc64 architecture. To mirror + * the behavior of the VM frame manager, we set fp to be the caller's (i.e., "sender's") + * stack pointer, which is the back chain value contained in our sp. + */ + Address fp = sp.getAddressAt(0); + setValues(null, null, null); // Assume we're not going to find anything + + VM vm = VM.getVM(); + if (vm.isJavaPCDbg(pc)) { + if (vm.isClientCompiler()) { + // Topmost frame is a Java frame. + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing compiler frame: sp = " + + sp + ", fp = " + fp + ", pc = " + pc); + } + setValues(sp, fp, pc); + return true; + } else { + if (vm.getInterpreter().contains(pc)) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " + + sp + ", fp = " + fp + ", pc = " + pc); + } + setValues(sp, fp, pc); + return true; + } + + // This algorithm takes the current PC as a given and tries to + // find the correct corresponding SP by walking up the stack + // and repeatedly performing stackwalks (very inefficient). + for (long offset = 0; + offset < regionInBytesToSearch; + offset += vm.getAddressSize()) { + try { + Address curSP = sp.addOffsetTo(offset); + fp = curSP.getAddressAt(0); + Frame frame = new PPC64Frame(curSP, fp, pc); + RegisterMap map = thread.newRegisterMap(false); + while (frame != null) { + if (frame.isEntryFrame() && frame.entryFrameIsFirst()) { + // We were able to traverse all the way to the + // bottommost Java frame. + // This sp looks good. Keep it. + if (DEBUG) { + System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc); + } + setValues(curSP, fp, pc); + return true; + } + frame = frame.sender(map); + } + } catch (Exception e) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset); + } + // Bad SP. Try another. + } + } + + // Were not able to find a plausible SP to go with this PC. + // Bail out. + return false; + + } + } else { + // If the current program counter was not known to us as a Java + // PC, we currently assume that we are in the run-time system + // and attempt to look to thread-local storage for saved java SP. + // Note that if this is null (because we were, in fact, + // in Java code, i.e., vtable stubs or similar, and the SA + // didn't have enough insight into the target VM to understand + // that) then we are going to lose the entire stack trace for + // the thread, which is sub-optimal. FIXME. + + if (thread.getLastJavaSP() == null) { + if (DEBUG) { + System.out.println("CurrentFrameGuess: last java sp is null"); + } + return false; // No known Java frames on stack + } + + Address javaSP = thread.getLastJavaSP(); + Address javaFP = javaSP.getAddressAt(0); + Address javaPC = thread.getLastJavaPC(); + if (DEBUG) { + System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " + + javaSP + ", fp = " + javaFP + ", pc = " + javaPC); + } + setValues(javaSP, javaFP, javaPC); + return true; + } + } + + public Address getSP() { return spFound; } + public Address getFP() { return fpFound; } + /** May be null if getting values from thread-local storage; take + care to call the correct PPC64Frame constructor to recover this if + necessary */ + public Address getPC() { return pcFound; } + + private void setValues(Address sp, Address fp, Address pc) { + spFound = sp; + fpFound = fp; + pcFound = pc; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,513 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import java.util.*; +import sun.jvm.hotspot.code.*; +import sun.jvm.hotspot.compiler.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.oops.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +/** Specialization of and implementation of abstract methods of the + Frame class for the ppc64 family of CPUs. */ + +public class PPC64Frame extends Frame { + private static final boolean DEBUG; + static { + DEBUG = System.getProperty("sun.jvm.hotspot.runtime.ppc64.PPC64Frame.DEBUG") != null; + } + + // All frames + private static final int SENDER_SP_OFFSET = 0; + + // Interpreter frames + private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only + private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4; + private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1; + private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1; + private static final int INTERPRETER_FRAME_ESP_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1; + private static final int INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_ESP_OFFSET - 1; + private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1; + private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1; + private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1; + private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1; + private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway + private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; + private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET; + + // Entry frames + private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET; + + // Native frames + private static int NATIVE_FRAME_INITIAL_PARAM_OFFSET; + + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + int abi_minframe_size = db.lookupIntConstant("frame::abi_minframe_size").intValue(); + int entry_frame_locals_size = db.lookupIntConstant("frame::entry_frame_locals_size").intValue(); + int wordLength = (int) VM.getVM().getAddressSize(); + NATIVE_FRAME_INITIAL_PARAM_OFFSET = -abi_minframe_size/wordLength; + ENTRY_FRAME_CALL_WRAPPER_OFFSET = -entry_frame_locals_size/wordLength; + } + + + // an additional field beyond sp and pc: + Address raw_fp; // frame pointer + private Address raw_unextendedSP; + + private PPC64Frame() { + } + + private void adjustForDeopt() { + if ( pc != null) { + // Look for a deopt pc and if it is deopted convert to original pc + CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc); + if (cb != null && cb.isJavaMethod()) { + NMethod nm = (NMethod) cb; + if (pc.equals(nm.deoptHandlerBegin())) { + if (Assert.ASSERTS_ENABLED) { + Assert.that(this.getUnextendedSP() != null, "null SP in Java frame"); + } + // adjust pc if frame is deoptimized. + pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset()); + deoptimized = true; + } + } + } + } + + public PPC64Frame(Address raw_sp, Address raw_fp, Address pc) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_sp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + if (pc == null) { + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + } else { + this.pc = pc; + } + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, fp, pc): " + this); + dumpStack(); + } + } + + public PPC64Frame(Address raw_sp, Address raw_fp) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_sp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, fp): " + this); + dumpStack(); + } + } + + public PPC64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) { + this.raw_sp = raw_sp; + this.raw_unextendedSP = raw_unextendedSp; + if (raw_fp == null) { + this.raw_fp = raw_sp.getAddressAt(0); + } else { + this.raw_fp = raw_fp; + } + if (pc == null) { + this.pc = raw_sp.getAddressAt(2 * VM.getVM().getAddressSize()); + } else { + this.pc = pc; + } + adjustUnextendedSP(); + + // Frame must be fully constructed before this call + adjustForDeopt(); + + if (DEBUG) { + System.out.println("PPC64Frame(sp, unextendedSP, fp, pc): " + this); + dumpStack(); + } + + } + + public Object clone() { + PPC64Frame frame = new PPC64Frame(); + frame.raw_sp = raw_sp; + frame.raw_unextendedSP = raw_unextendedSP; + frame.raw_fp = raw_fp; + frame.pc = pc; + frame.deoptimized = deoptimized; + return frame; + } + + public boolean equals(Object arg) { + if (arg == null) { + return false; + } + + if (!(arg instanceof PPC64Frame)) { + return false; + } + + PPC64Frame other = (PPC64Frame) arg; + + return (AddressOps.equal(getSP(), other.getSP()) && + AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) && + AddressOps.equal(getFP(), other.getFP()) && + AddressOps.equal(getPC(), other.getPC())); + } + + public int hashCode() { + if (raw_sp == null) { + return 0; + } + + return raw_sp.hashCode(); + } + + public String toString() { + return "sp: " + (getSP() == null ? "null" : getSP().toString()) + + ", unextendedSP: " + (getUnextendedSP() == null ? "null" : getUnextendedSP().toString()) + + ", fp: " + (getFP() == null ? "null" : getFP().toString()) + + ", pc: " + (pc == null ? "null" : pc.toString()); + } + + // accessors for the instance variables + public Address getFP() { return raw_fp; } + public Address getSP() { return raw_sp; } + public Address getID() { return raw_sp; } + + // FIXME: not implemented yet (should be done for Solaris/PPC64) + public boolean isSignalHandlerFrameDbg() { return false; } + public int getSignalNumberDbg() { return 0; } + public String getSignalNameDbg() { return null; } + + public boolean isInterpretedFrameValid() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isInterpretedFrame(), "Not an interpreted frame"); + } + + // These are reasonable sanity checks + if (getFP() == null || getFP().andWithMask(0x3) != null) { + return false; + } + + if (getSP() == null || getSP().andWithMask(0x3) != null) { + return false; + } + + // These are hacks to keep us out of trouble. + // The problem with these is that they mask other problems + if (getFP().lessThanOrEqual(getSP())) { + // this attempts to deal with unsigned comparison above + return false; + } + + if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) { + // stack frames shouldn't be large. + return false; + } + + return true; + } + + // FIXME: not applicable in current system + // void patch_pc(Thread* thread, address pc); + + public Frame sender(RegisterMap regMap, CodeBlob cb) { + PPC64RegisterMap map = (PPC64RegisterMap) regMap; + + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + + // Default is we done have to follow them. The sender_for_xxx will + // update it accordingly + map.setIncludeArgumentOops(false); + + if (isEntryFrame()) return senderForEntryFrame(map); + if (isInterpretedFrame()) return senderForInterpreterFrame(map); + + if(cb == null) { + cb = VM.getVM().getCodeCache().findBlob(getPC()); + } else { + if (Assert.ASSERTS_ENABLED) { + Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same"); + } + } + + if (cb != null) { + return senderForCompiledFrame(map, cb); + } + + // Must be native-compiled frame, i.e. the marshaling code for native + // methods that exists in the core system. + return new PPC64Frame(getSenderSP(), getLink(), getSenderPC()); + } + + private Frame senderForEntryFrame(PPC64RegisterMap map) { + if (DEBUG) { + System.out.println("senderForEntryFrame"); + } + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + // Java frame called from C; skip all C frames and return top C + // frame of that chunk as the sender + PPC64JavaCallWrapper jcw = (PPC64JavaCallWrapper) getEntryFrameCallWrapper(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero"); + Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack"); + } + PPC64Frame fr; + if (jcw.getLastJavaPC() != null) { + fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC()); + } else { + fr = new PPC64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP()); + } + map.clear(); + if (Assert.ASSERTS_ENABLED) { + Assert.that(map.getIncludeArgumentOops(), "should be set by clear"); + } + return fr; + } + + //------------------------------------------------------------------------------ + // frame::adjust_unextended_sp + private void adjustUnextendedSP() { + raw_unextendedSP = getFP(); + } + private Frame senderForInterpreterFrame(PPC64RegisterMap map) { + if (DEBUG) { + System.out.println("senderForInterpreterFrame"); + } + Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); + Address sp = getSenderSP(); + + return new PPC64Frame(sp, unextendedSP, getLink(), getSenderPC()); + } + + + private Frame senderForCompiledFrame(PPC64RegisterMap map, CodeBlob cb) { + if (DEBUG) { + System.out.println("senderForCompiledFrame"); + } + + // + // NOTE: some of this code is (unfortunately) duplicated in PPC64CurrentFrameGuess + // + + if (Assert.ASSERTS_ENABLED) { + Assert.that(map != null, "map must be set"); + } + + // frame owned by optimizing compiler + if (Assert.ASSERTS_ENABLED) { + Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size"); + } + Address senderSP = getSenderSP(); + + Address senderPC = getSenderPC(); + + if (map.getUpdateMap()) { + // Tell GC to use argument oopmaps for some runtime stubs that need it. + // For C1, the runtime stub might not have oop maps, so set this flag + // outside of update_register_map. + map.setIncludeArgumentOops(cb.callerMustGCArguments()); + + if (cb.getOopMaps() != null) { + OopMapSet.updateRegisterMap(this, cb, map, true); + } + } + + return new PPC64Frame(senderSP, getLink(), senderPC); + } + + protected boolean hasSenderPD() { + // FIXME + return true; + } + + public long frameSize() { + return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize()); + } + + public Address getLink() { + return getSenderSP().getAddressAt(0); + } + + public Address getUnextendedSP() { return raw_unextendedSP; } + + // Return address: + public Address getSenderPC() { return getSenderSP().getAddressAt(2 * VM.getVM().getAddressSize()); } + + // return address of param, zero origin index. + // MPJ note: Appears to be unused. + public Address getNativeParamAddr(int idx) { + return null; + // return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx); + } + + public Address getSenderSP() { return getFP(); } + public Address addressOfInterpreterFrameLocals() { + return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET); + } + + private Address addressOfInterpreterFrameBCX() { + return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET); + } + + public int getInterpreterFrameBCI() { + // FIXME: this is not atomic with respect to GC and is unsuitable + // for use in a non-debugging, or reflective, system. Need to + // figure out how to express this. + Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0); + Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0); + Method method = (Method)Metadata.instantiateWrapperFor(methodHandle); + return bcpToBci(bcp, method); + } + + public Address addressOfInterpreterFrameMDX() { + return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET); + } + + // FIXME + //inline int frame::interpreter_frame_monitor_size() { + // return BasicObjectLock::size(); + //} + + // expression stack + // (the max_stack arguments are used by the GC; see class FrameClosure) + + public Address addressOfInterpreterFrameExpressionStack() { + Address monitorEnd = interpreterFrameMonitorEnd().address(); + return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize()); + } + + public int getInterpreterFrameExpressionStackDirection() { return -1; } + + // top of expression stack + public Address addressOfInterpreterFrameTOS() { + return getSP(); + } + + /** Expression stack from top down */ + public Address addressOfInterpreterFrameTOSAt(int slot) { + return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize()); + } + + public Address getInterpreterFrameSenderSP() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isInterpretedFrame(), "interpreted frame expected"); + } + return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0); + } + + // Monitors + public BasicObjectLock interpreterFrameMonitorBegin() { + return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET)); + } + + public BasicObjectLock interpreterFrameMonitorEnd() { + Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0); + if (Assert.ASSERTS_ENABLED) { + // make sure the pointer points inside the frame + Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer"); + Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer"); + } + return new BasicObjectLock(result); + } + + public int interpreterFrameMonitorSize() { + return BasicObjectLock.size(); + } + + // Method + public Address addressOfInterpreterFrameMethod() { + return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET); + } + + // Constant pool cache + public Address addressOfInterpreterFrameCPCache() { + return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET); + } + + // Entry frames + public JavaCallWrapper getEntryFrameCallWrapper() { + return new PPC64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0)); + } + + protected Address addressOfSavedOopResult() { + // offset is 2 for compiler2 and 3 for compiler1 + return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) * + VM.getVM().getAddressSize()); + } + + protected Address addressOfSavedReceiver() { + return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize()); + } + + private void dumpStack() { + if (getFP() != null) { + for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); + AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize())); + addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { + System.out.println(addr + ": " + addr.getAddressAt(0)); + } + } else { + for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize()); + AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize())); + addr = addr.addOffsetTo(VM.getVM().getAddressSize())) { + System.out.println(addr + ": " + addr.getAddressAt(0)); + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import java.util.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.runtime.*; + +public class PPC64JavaCallWrapper extends JavaCallWrapper { + + public PPC64JavaCallWrapper(Address addr) { + super(addr); + } + + public Address getLastJavaFP() { + return null; + } + +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 20014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.ppc64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.runtime.*; + +public class PPC64RegisterMap extends RegisterMap { + + /** This is the only public constructor */ + public PPC64RegisterMap(JavaThread thread, boolean updateMap) { + super(thread, updateMap); + } + + protected PPC64RegisterMap(RegisterMap map) { + super(map); + } + + public Object clone() { + PPC64RegisterMap retval = new PPC64RegisterMap(this); + return retval; + } + + // no PD state to clear or copy: + protected void clearPD() {} + protected void initializePD() {} + protected void initializeFromPD(RegisterMap map) {} + protected Address getLocationPD(VMReg reg) { return null; } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/make/aix/makefiles/ppc64.make --- a/hotspot/make/aix/makefiles/ppc64.make Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/make/aix/makefiles/ppc64.make Tue Jan 20 10:22:44 2015 -0800 @@ -46,7 +46,9 @@ # - 1540-1090 (I) The destructor of "..." might not be called. # - 1500-010: (W) WARNING in ...: Infinite loop. Program may not stop. # There are several infinite loops in the vm, suppress. -CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010 +# - 1540-1639 (I) The behavior of long type bit fields has changed ... +# ... long type bit fields now default to long, not int. +CFLAGS += -qsuppress=1540-1090 -qsuppress=1500-010 -qsuppress=1540-1639 # Suppress # - 540-1088 (W) The exception specification is being ignored. diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/make/aix/makefiles/xlc.make --- a/hotspot/make/aix/makefiles/xlc.make Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/make/aix/makefiles/xlc.make Tue Jan 20 10:22:44 2015 -0800 @@ -124,7 +124,7 @@ # MAPFLAG = -Xlinker --version-script=FILENAME # Build shared library -SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath +SHARED_FLAG = -q64 -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok #------------------------------------------------------------------------ # Debug flags diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/make/linux/makefiles/sa.make --- a/hotspot/make/linux/makefiles/sa.make Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/make/linux/makefiles/sa.make Tue Jan 20 10:22:44 2015 -0800 @@ -109,6 +109,7 @@ $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext + $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ppc64.PPC64ThreadContext $(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler clean: diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/make/sa.files --- a/hotspot/make/sa.files Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/make/sa.files Tue Jan 20 10:22:44 2015 -0800 @@ -51,16 +51,20 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/dummy/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/elf/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/amd64/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \ @@ -90,12 +94,14 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/posix/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_amd64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/solaris_x86/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/sparc/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/x86/*.java \ +$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/ppc64/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/jcore/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/tools/soql/*.java \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/ci/ciInstanceKlass.cpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -59,7 +59,7 @@ _has_nonstatic_fields = ik->has_nonstatic_fields(); _has_default_methods = ik->has_default_methods(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: - + _has_injected_fields = -1; _implementor = NULL; // we will fill these lazily Thread *thread = Thread::current(); @@ -100,6 +100,7 @@ _nonstatic_field_size = -1; _has_nonstatic_fields = false; _nonstatic_fields = NULL; + _has_injected_fields = -1; _loader = loader; _protection_domain = protection_domain; _is_shared = false; @@ -500,6 +501,34 @@ return fields; } +void ciInstanceKlass::compute_injected_fields_helper() { + ASSERT_IN_VM; + InstanceKlass* k = get_instanceKlass(); + + for (InternalFieldStream fs(k); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) continue; + _has_injected_fields++; + break; + } +} + +bool ciInstanceKlass::compute_injected_fields() { + assert(_has_injected_fields == -1, "shouldn't be initialized yet"); + assert(is_loaded(), "must be loaded"); + + if (super() != NULL && super()->has_injected_fields()) { + _has_injected_fields = 1; + return true; + } + + _has_injected_fields = 0; + GUARDED_VM_ENTRY({ + compute_injected_fields_helper(); + }); + + return _has_injected_fields > 0 ? true : false; +} + // ------------------------------------------------------------------ // ciInstanceKlass::find_method // diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/ci/ciInstanceKlass.hpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -64,6 +64,7 @@ ciConstantPoolCache* _field_cache; // cached map index->field GrowableArray* _nonstatic_fields; + int _has_injected_fields; // any non static injected fields? lazily initialized. // The possible values of the _implementor fall into following three cases: // NULL: no implementor. @@ -71,6 +72,9 @@ // Itsef: more than one implementors. ciInstanceKlass* _implementor; + bool compute_injected_fields(); + void compute_injected_fields_helper(); + protected: ciInstanceKlass(KlassHandle h_k); ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); @@ -186,6 +190,14 @@ else return _nonstatic_fields->length(); } + + bool has_injected_fields() { + if (_has_injected_fields == -1) { + return compute_injected_fields(); + } + return _has_injected_fields > 0 ? true : false; + } + // nth nonstatic field (presented by ascending address) ciField* nonstatic_field_at(int i) { assert(_nonstatic_fields != NULL, ""); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -786,17 +786,12 @@ MetadataOnStackMark md_on_stack(has_redefined_a_class); if (has_redefined_a_class) { - // purge_previous_versions also cleans weak method links. Because - // one method's MDO can reference another method from another - // class loader, we need to first clean weak method links for all - // class loaders here. Below, we can then free redefined methods - // for all class loaders. for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { data->classes_do(InstanceKlass::purge_previous_versions); } } - // Need to purge the previous version before deallocating. + // Should purge the previous version before deallocating. free_deallocate_lists(); } @@ -834,8 +829,6 @@ void ClassLoaderDataGraph::free_deallocate_lists() { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - // We need to keep this data until InstanceKlass::purge_previous_version has been - // called on all alive classes. See the comment in ClassLoaderDataGraph::clean_metaspaces. cld->free_deallocate_list(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/compactHashtable.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,417 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "classfile/javaClasses.hpp" +#include "memory/metaspaceShared.hpp" +#include "utilities/numberSeq.hpp" +#include + +///////////////////////////////////////////////////// +// +// The compact hash table writer implementations +// +CompactHashtableWriter::CompactHashtableWriter(const char* table_name, + int num_entries, + CompactHashtableStats* stats) { + assert(DumpSharedSpaces, "dump-time only"); + _table_name = table_name; + _num_entries = num_entries; + _num_buckets = number_of_buckets(_num_entries); + _buckets = NEW_C_HEAP_ARRAY(Entry*, _num_buckets, mtSymbol); + memset(_buckets, 0, sizeof(Entry*) * _num_buckets); + + /* bucket sizes table */ + _bucket_sizes = NEW_C_HEAP_ARRAY(juint, _num_buckets, mtSymbol); + memset(_bucket_sizes, 0, sizeof(juint) * _num_buckets); + + stats->hashentry_count = _num_entries; + // Compact buckets' entries will have only the 4-byte offset, but + // we don't know how many there will be at this point. So use a + // conservative estimate here. The size is adjusted later when we + // write out the buckets. + stats->hashentry_bytes = _num_entries * 8; + stats->bucket_count = _num_buckets; + stats->bucket_bytes = (_num_buckets + 1) * (sizeof(juint)); + _stats = stats; + + // See compactHashtable.hpp for table layout + _required_bytes = sizeof(juint) * 2; // _base_address, written as 2 juints + _required_bytes+= sizeof(juint) + // num_entries + sizeof(juint) + // num_buckets + stats->hashentry_bytes + + stats->bucket_bytes; +} + +CompactHashtableWriter::~CompactHashtableWriter() { + for (int index = 0; index < _num_buckets; index++) { + Entry* next = NULL; + for (Entry* tent = _buckets[index]; tent; tent = next) { + next = tent->next(); + delete tent; + } + } + + FREE_C_HEAP_ARRAY(juint, _bucket_sizes); + FREE_C_HEAP_ARRAY(Entry*, _buckets); +} + +// Calculate the number of buckets in the temporary hash table +int CompactHashtableWriter::number_of_buckets(int num_entries) { + const int buksize = (int)SharedSymbolTableBucketSize; + int num_buckets = (num_entries + buksize - 1) / buksize; + num_buckets = (num_buckets + 1) & (~0x01); + + return num_buckets; +} + +// Add a symbol entry to the temporary hash table +void CompactHashtableWriter::add(unsigned int hash, Entry* entry) { + int index = hash % _num_buckets; + entry->set_next(_buckets[index]); + _buckets[index] = entry; + _bucket_sizes[index] ++; +} + +// Write the compact table's bucket infos +juint* CompactHashtableWriter::dump_table(juint* p, juint** first_bucket, + NumberSeq* summary) { + int index; + juint* compact_table = p; + // Find the start of the buckets, skip the compact_bucket_infos table + // and the table end offset. + juint offset = _num_buckets + 1; + *first_bucket = compact_table + offset; + + for (index = 0; index < _num_buckets; index++) { + int bucket_size = _bucket_sizes[index]; + if (bucket_size == 1) { + // bucket with one entry is compacted and only has the symbol offset + compact_table[index] = BUCKET_INFO(offset, COMPACT_BUCKET_TYPE); + offset += bucket_size; // each entry contains symbol offset only + } else { + // regular bucket, each entry is a symbol (hash, offset) pair + compact_table[index] = BUCKET_INFO(offset, REGULAR_BUCKET_TYPE); + offset += bucket_size * 2; // each hash entry is 2 juints + } + if (offset & ~BUCKET_OFFSET_MASK) { + vm_exit_during_initialization("CompactHashtableWriter::dump_table: Overflow! " + "Too many symbols."); + } + summary->add(bucket_size); + } + // Mark the end of the table + compact_table[_num_buckets] = BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE); + + return compact_table; +} + +// Write the compact table's entries +juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p, + NumberSeq* summary) { + uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); + uintx max_delta = uintx(MetaspaceShared::shared_rs()->size()); + assert(max_delta <= 0x7fffffff, "range check"); + int num_compact_buckets = 0; + + assert(p != NULL, "sanity"); + for (int index = 0; index < _num_buckets; index++) { + juint count = 0; + int bucket_size = _bucket_sizes[index]; + int bucket_type = BUCKET_TYPE(compact_table[index]); + + if (bucket_size == 1) { + assert(bucket_type == COMPACT_BUCKET_TYPE, "Bad bucket type"); + num_compact_buckets ++; + } + for (Entry* tent = _buckets[index]; tent; + tent = tent->next()) { + if (bucket_type == REGULAR_BUCKET_TYPE) { + *p++ = juint(tent->hash()); // write symbol hash + } + uintx deltax = uintx(tent->value()) - base_address; + assert(deltax < max_delta, "range check"); + juint delta = juint(deltax); + *p++ = delta; // write symbol offset + count ++; + } + assert(count == _bucket_sizes[index], "sanity"); + } + + // Adjust the hashentry_bytes in CompactHashtableStats. Each compact + // bucket saves 4-byte. + _stats->hashentry_bytes -= num_compact_buckets * 4; + + return p; +} + +// Write the compact table +void CompactHashtableWriter::dump(char** top, char* end) { + NumberSeq summary; + char* old_top = *top; + juint* p = (juint*)(*top); + + uintx base_address = uintx(MetaspaceShared::shared_rs()->base()); + + *p++ = high(base_address); + *p++ = low (base_address); // base address + *p++ = _num_entries; // number of entries in the table + *p++ = _num_buckets; // number of buckets in the table + + juint* first_bucket = NULL; + juint* compact_table = dump_table(p, &first_bucket, &summary); + juint* bucket_end = dump_buckets(compact_table, first_bucket, &summary); + + assert(bucket_end <= (juint*)end, "cannot write past end"); + *top = (char*)bucket_end; + + if (PrintSharedSpaces) { + double avg_cost = 0.0; + if (_num_entries > 0) { + avg_cost = double(_required_bytes)/double(_num_entries); + } + tty->print_cr("Shared %s table stats -------- base: " PTR_FORMAT, _table_name, (intptr_t)base_address); + tty->print_cr("Number of entries : %9d", _num_entries); + tty->print_cr("Total bytes used : %9d", (int)((*top) - old_top)); + tty->print_cr("Average bytes per entry : %9.3f", avg_cost); + tty->print_cr("Average bucket size : %9.3f", summary.avg()); + tty->print_cr("Variance of bucket size : %9.3f", summary.variance()); + tty->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); + tty->print_cr("Maximum bucket size : %9d", (int)summary.maximum()); + } +} + +///////////////////////////////////////////////////////////// +// +// The CompactHashtable implementation +// +template const char* CompactHashtable::init(const char* buffer) { + assert(!DumpSharedSpaces, "run-time only"); + juint*p = (juint*)buffer; + juint upper = *p++; + juint lower = *p++; + _base_address = uintx(jlong_from(upper, lower)); + _entry_count = *p++; + _bucket_count = *p++; + _buckets = p; + _table_end_offset = BUCKET_OFFSET(p[_bucket_count]); // located at the end of the bucket_info table + + juint *end = _buckets + _table_end_offset; + return (const char*)end; +} + +// Explicitly instantiate these types +template class CompactHashtable; + +#ifndef O_BINARY // if defined (Win32) use binary files. +#define O_BINARY 0 // otherwise do nothing. +#endif + +//////////////////////////////////////////////////////// +// +// HashtableTextDump +// +HashtableTextDump::HashtableTextDump(const char* filename) : _fd(-1) { + struct stat st; + if (os::stat(filename, &st) != 0) { + quit("Unable to get hashtable dump file size", filename); + } + _size = st.st_size; + _fd = open(filename, O_RDONLY | O_BINARY, 0); + if (_fd < 0) { + quit("Unable to open hashtable dump file", filename); + } + _base = os::map_memory(_fd, filename, 0, NULL, _size, true, false); + if (_base == NULL) { + quit("Unable to map hashtable dump file", filename); + } + _p = _base; + _end = _base + st.st_size; + _filename = filename; +} + +HashtableTextDump::~HashtableTextDump() { + os::unmap_memory((char*)_base, _size); + if (_fd >= 0) { + close(_fd); + } +} + +void HashtableTextDump::quit(const char* err, const char* msg) { + vm_exit_during_initialization(err, msg); +} + +void HashtableTextDump::corrupted(const char *p) { + char info[60]; + sprintf(info, "corrupted at pos %d", (int)(p - _base)); + quit(info, _filename); +} + +bool HashtableTextDump::skip_newline() { + if (_p[0] == '\r' && _p[1] == '\n') { + _p += 2; + } else if (_p[0] == '\n') { + _p += 1; + } else { + corrupted(_p); + } + return true; +} + +int HashtableTextDump::skip(char must_be_char) { + corrupted_if(remain() < 1); + corrupted_if(*_p++ != must_be_char); + return 0; +} + +void HashtableTextDump::skip_past(char c) { + for (;;) { + corrupted_if(remain() < 1); + if (*_p++ == c) { + return; + } + } +} + +void HashtableTextDump::check_version(const char* ver) { + int len = (int)strlen(ver); + corrupted_if(remain() < len); + if (strncmp(_p, ver, len) != 0) { + quit("wrong version of hashtable dump file", _filename); + } + _p += len; + skip_newline(); +} + + +int HashtableTextDump::scan_prefix() { + // Expect /[0-9]+: / + int utf8_length = get_num(':'); + if (*_p != ' ') { + corrupted(_p); + } + _p++; + return utf8_length; +} + +int HashtableTextDump::scan_prefix2() { + // Expect /[0-9]+ (-|)[0-9]+: / + int utf8_length = get_num(' '); + if (*_p == '-') { + _p++; + } + (void)get_num(':'); + if (*_p != ' ') { + corrupted(_p); + } + _p++; + return utf8_length; +} + +jchar HashtableTextDump::unescape(const char* from, const char* end, int count) { + jchar value = 0; + + corrupted_if(from + count > end); + + for (int i=0; i 0 && from < end; n--) { + if (*from != '\\') { + *to++ = *from++; + } else { + corrupted_if(from + 2 > end); + char c = from[1]; + from += 2; + switch (c) { + case 'x': + { + jchar value = unescape(from, end, 2); + from += 2; + assert(value <= 0xff, "sanity"); + *to++ = (char)(value & 0xff); + } + break; + case 't': *to++ = '\t'; break; + case 'n': *to++ = '\n'; break; + case 'r': *to++ = '\r'; break; + case '\\': *to++ = '\\'; break; + default: + ShouldNotReachHere(); + } + } + } + corrupted_if(n > 0); // expected more chars but file has ended + _p = from; + skip_newline(); +} + +// NOTE: the content is NOT the same as +// UTF8::as_quoted_ascii(const char* utf8_str, int utf8_length, char* buf, int buflen). +// We want to escape \r\n\t so that output [1] is more readable; [2] can be more easily +// parsed by scripts; [3] quickly processed by HashtableTextDump::get_utf8() +void HashtableTextDump::put_utf8(outputStream* st, const char* utf8_string, int utf8_length) { + const char *c = utf8_string; + const char *end = c + utf8_length; + for (; c < end; c++) { + switch (*c) { + case '\t': st->print("\\t"); break; + case '\r': st->print("\\r"); break; + case '\n': st->print("\\n"); break; + case '\\': st->print("\\\\"); break; + default: + if (isprint(*c)) { + st->print("%c", *c); + } else { + st->print("\\x%02x", ((unsigned int)*c) & 0xff); + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/compactHashtable.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,405 @@ +/* + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP +#define SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP + +#include "classfile/stringTable.hpp" +#include "classfile/symbolTable.hpp" +#include "memory/allocation.inline.hpp" +#include "oops/symbol.hpp" +#include "services/diagnosticCommand.hpp" +#include "utilities/hashtable.hpp" + +class NumberSeq; + +// Stats for symbol tables in the CDS archive +class CompactHashtableStats VALUE_OBJ_CLASS_SPEC { +public: + int hashentry_count; + int hashentry_bytes; + int bucket_count; + int bucket_bytes; +}; + +///////////////////////////////////////////////////////////////////////// +// +// The compact hash table writer. Used at dump time for writing out +// the compact table to the shared archive. +// +// At dump time, the CompactHashtableWriter obtains all entries from the +// symbol table and adds them to a new temporary hash table. The hash +// table size (number of buckets) is calculated using +// '(num_entries + bucket_size - 1) / bucket_size'. The default bucket +// size is 4 and can be changed by -XX:SharedSymbolTableBucketSize option. +// 4 is chosen because it produces smaller sized bucket on average for +// faster lookup. It also has relatively small number of empty buckets and +// good distribution of the entries. +// +// We use a simple hash function (symbol_hash % num_bucket) for the table. +// The new table is compacted when written out. Please see comments +// above the CompactHashtable class for the table layout detail. The bucket +// offsets are written to the archive as part of the compact table. The +// bucket offset is encoded in the low 30-bit (0-29) and the bucket type +// (regular or compact) are encoded in bit[31, 30]. For buckets with more +// than one entry, both symbol hash and symbol offset are written to the +// table. For buckets with only one entry, only the symbol offset is written +// to the table and the buckets are tagged as compact in their type bits. +// Buckets without entry are skipped from the table. Their offsets are +// still written out for faster lookup. +// +class CompactHashtableWriter: public StackObj { +public: + class Entry: public CHeapObj { + Entry* _next; + unsigned int _hash; + void* _literal; + + public: + Entry(unsigned int hash, Symbol *symbol) : _next(NULL), _hash(hash), _literal(symbol) {} + + void *value() { + return _literal; + } + Symbol *symbol() { + return (Symbol*)_literal; + } + unsigned int hash() { + return _hash; + } + Entry *next() {return _next;} + void set_next(Entry *p) {_next = p;} + }; // class CompactHashtableWriter::Entry + +private: + static int number_of_buckets(int num_entries); + + const char* _table_name; + int _num_entries; + int _num_buckets; + juint* _bucket_sizes; + Entry** _buckets; + int _required_bytes; + CompactHashtableStats* _stats; + +public: + // This is called at dump-time only + CompactHashtableWriter(const char* table_name, int num_entries, CompactHashtableStats* stats); + ~CompactHashtableWriter(); + + int get_required_bytes() { + return _required_bytes; + } + + void add(unsigned int hash, Symbol* symbol) { + add(hash, new Entry(hash, symbol)); + } + +private: + void add(unsigned int hash, Entry* entry); + juint* dump_table(juint* p, juint** first_bucket, NumberSeq* summary); + juint* dump_buckets(juint* table, juint* p, NumberSeq* summary); + +public: + void dump(char** top, char* end); +}; + +#define REGULAR_BUCKET_TYPE 0 +#define COMPACT_BUCKET_TYPE 1 +#define TABLEEND_BUCKET_TYPE 3 +#define BUCKET_OFFSET_MASK 0x3FFFFFFF +#define BUCKET_OFFSET(info) ((info) & BUCKET_OFFSET_MASK) +#define BUCKET_TYPE_SHIFT 30 +#define BUCKET_TYPE(info) (((info) & ~BUCKET_OFFSET_MASK) >> BUCKET_TYPE_SHIFT) +#define BUCKET_INFO(offset, type) (((type) << BUCKET_TYPE_SHIFT) | ((offset) & BUCKET_OFFSET_MASK)) + +///////////////////////////////////////////////////////////////////////////// +// +// CompactHashtable is used to stored the CDS archive's symbol table. Used +// at runtime only to access the compact table from the archive. +// +// Because these tables are read-only (no entries can be added/deleted) at run-time +// and tend to have large number of entries, we try to minimize the footprint +// cost per entry. +// +// Layout of compact symbol table in the shared archive: +// +// uintx base_address; +// juint num_symbols; +// juint num_buckets; +// juint bucket_infos[num_buckets+1]; // bit[31,30]: type; bit[29-0]: offset +// juint table[] +// +// ----------------------------------- +// | base_address | num_symbols | +// |---------------------------------| +// | num_buckets | bucket_info0 | +// |---------------------------------| +// | bucket_info1 | bucket_info2 | +// | bucket_info3 ... | +// | .... | table_end_info | +// |---------------------------------| +// | entry0 | +// | entry1 | +// | entry2 | +// | | +// | ... | +// ----------------------------------- +// +// The size of the bucket_info table is 'num_buckets + 1'. Each entry of the +// bucket_info table is a 32-bit encoding of the bucket type and bucket offset, +// with the type in the left-most 2-bit and offset in the remaining 30-bit. +// The last entry is a special type. It contains the offset of the last +// bucket end. We use that information when traversing the compact table. +// +// There are two types of buckets, regular buckets and compact buckets. The +// compact buckets have '01' in their highest 2-bit, and regular buckets have +// '00' in their highest 2-bit. +// +// For normal buckets, each symbol's entry is 8 bytes in the table[]: +// juint hash; /* symbol hash */ +// juint offset; /* Symbol* sym = (Symbol*)(base_address + offset) */ +// +// For compact buckets, each entry has only the 4-byte 'offset' in the table[]. +// +// See CompactHashtable::lookup() for how the table is searched at runtime. +// See CompactHashtableWriter::dump() for how the table is written at CDS +// dump time. +// +template class CompactHashtable VALUE_OBJ_CLASS_SPEC { + uintx _base_address; + juint _entry_count; + juint _bucket_count; + juint _table_end_offset; + juint* _buckets; + + inline bool equals(T entry, const char* name, int len) { + if (entry->equals(name, len)) { + assert(entry->refcount() == -1, "must be shared"); + return true; + } else { + return false; + } + } + +public: + CompactHashtable() { + _entry_count = 0; + _bucket_count = 0; + _table_end_offset = 0; + _buckets = 0; + } + const char* init(const char *buffer); + + // Lookup an entry from the compact table + inline T lookup(const N* name, unsigned int hash, int len) { + if (_entry_count > 0) { + assert(!DumpSharedSpaces, "run-time only"); + int index = hash % _bucket_count; + juint bucket_info = _buckets[index]; + juint bucket_offset = BUCKET_OFFSET(bucket_info); + int bucket_type = BUCKET_TYPE(bucket_info); + juint* bucket = _buckets + bucket_offset; + juint* bucket_end = _buckets; + + if (bucket_type == COMPACT_BUCKET_TYPE) { + // the compact bucket has one entry with symbol offset only + T entry = (T)((void*)(_base_address + bucket[0])); + if (equals(entry, name, len)) { + return entry; + } + } else { + // This is a regular bucket, which has more than one + // entries. Each entry is a pair of symbol (hash, offset). + // Seek until the end of the bucket. + bucket_end += BUCKET_OFFSET(_buckets[index + 1]); + while (bucket < bucket_end) { + unsigned int h = (unsigned int)(bucket[0]); + if (h == hash) { + juint offset = bucket[1]; + T entry = (T)((void*)(_base_address + offset)); + if (equals(entry, name, len)) { + return entry; + } + } + bucket += 2; + } + } + } + return NULL; + } +}; + +//////////////////////////////////////////////////////////////////////// +// +// Read/Write the contents of a hashtable textual dump (created by +// SymbolTable::dump). +// Because the dump file may be big (hundred of MB in extreme cases), +// we use mmap for fast access when reading it. +// +class HashtableTextDump VALUE_OBJ_CLASS_SPEC { + int _fd; + const char* _base; + const char* _p; + const char* _end; + const char* _filename; + size_t _size; +public: + HashtableTextDump(const char* filename); + ~HashtableTextDump(); + + void quit(const char* err, const char* msg); + + inline int remain() { + return (int)(_end - _p); + } + + void corrupted(const char *p); + + inline void corrupted_if(bool cond) { + if (cond) { + corrupted(_p); + } + } + + bool skip_newline(); + int skip(char must_be_char); + void skip_past(char c); + void check_version(const char* ver); + + inline int get_num(char delim) { + const char* p = _p; + const char* end = _end; + int num = 0; + + while (p < end) { + char c = *p ++; + if ('0' <= c && c <= '9') { + num = num * 10 + (c - '0'); + } else if (c == delim) { + _p = p; + return num; + } else { + corrupted(p-1); + } + } + corrupted(_end); + ShouldNotReachHere(); + return 0; + } + + int scan_prefix(); + int scan_prefix2(); + + jchar unescape(const char* from, const char* end, int count); + void get_utf8(char* utf8_buffer, int utf8_length); + static void put_utf8(outputStream* st, const char* utf8_string, int utf8_length); +}; + +/////////////////////////////////////////////////////////////////////// +// +// jcmd command support for symbol table and string table dumping: +// VM.symboltable -verbose: for dumping the symbol table +// VM.stringtable -verbose: for dumping the string table +// +class VM_DumpHashtable : public VM_Operation { +private: + outputStream* _out; + int _which; + bool _verbose; +public: + enum { + DumpSymbols = 1 << 0, + DumpStrings = 1 << 1, + DumpSysDict = 1 << 2 // not implemented yet + }; + VM_DumpHashtable(outputStream* out, int which, bool verbose) { + _out = out; + _which = which; + _verbose = verbose; + } + + virtual VMOp_Type type() const { return VMOp_DumpHashtable; } + + virtual void doit() { + switch (_which) { + case DumpSymbols: + SymbolTable::dump(_out, _verbose); + break; + case DumpStrings: + StringTable::dump(_out, _verbose); + break; + default: + ShouldNotReachHere(); + } + } +}; + +class SymboltableDCmd : public DCmdWithParser { +protected: + DCmdArgument _verbose; +public: + SymboltableDCmd(outputStream* output, bool heap); + static const char* name() { + return "VM.symboltable"; + } + static const char* description() { + return "Dump symbol table."; + } + static const char* impact() { + return "Medium: Depends on Java content."; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments(); + virtual void execute(DCmdSource source, TRAPS); +}; + +class StringtableDCmd : public DCmdWithParser { +protected: + DCmdArgument _verbose; +public: + StringtableDCmd(outputStream* output, bool heap); + static const char* name() { + return "VM.stringtable"; + } + static const char* description() { + return "Dump string table."; + } + static const char* impact() { + return "Medium: Depends on Java content."; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments(); + virtual void execute(DCmdSource source, TRAPS); +}; + +#endif // SHARE_VM_CLASSFILE_COMPACTHASHTABLE_HPP diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/stringTable.cpp --- a/hotspot/src/share/vm/classfile/stringTable.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/stringTable.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" @@ -379,8 +380,36 @@ } } -void StringTable::dump(outputStream* st) { - the_table()->dump_table(st, "StringTable"); +void StringTable::dump(outputStream* st, bool verbose) { + if (!verbose) { + the_table()->dump_table(st, "StringTable"); + } else { + Thread* THREAD = Thread::current(); + st->print_cr("VERSION: 1.1"); + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + oop s = p->literal(); + typeArrayOop value = java_lang_String::value(s); + int offset = java_lang_String::offset(s); + int length = java_lang_String::length(s); + + if (length <= 0) { + st->print("%d: ", length); + } else { + ResourceMark rm(THREAD); + jchar* chars = (jchar*)value->char_at_addr(offset); + int utf8_length = UNICODE::utf8_length(chars, length); + char* utf8_string = NEW_RESOURCE_ARRAY(char, utf8_length + 1); + UNICODE::convert_to_utf8(chars, length, utf8_string); + + st->print("%d: ", utf8_length); + HashtableTextDump::put_utf8(st, utf8_string, utf8_length); + } + st->cr(); + } + } + } } StringTable::VerifyRetTypes StringTable::compare_entries( @@ -558,3 +587,28 @@ _needs_rehashing = false; _the_table = new_table; } + +// Utility for dumping strings +StringtableDCmd::StringtableDCmd(outputStream* output, bool heap) : + DCmdWithParser(output, heap), + _verbose("-verbose", "Dump the content of each string in the table", + "BOOLEAN", false, "false") { + _dcmdparser.add_dcmd_option(&_verbose); +} + +void StringtableDCmd::execute(DCmdSource source, TRAPS) { + VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpStrings, + _verbose.value()); + VMThread::execute(&dumper); +} + +int StringtableDCmd::num_arguments() { + ResourceMark rm; + StringtableDCmd* dcmd = new StringtableDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/stringTable.hpp --- a/hotspot/src/share/vm/classfile/stringTable.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/stringTable.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -118,7 +118,7 @@ // Debugging static void verify(); - static void dump(outputStream* st); + static void dump(outputStream* st, bool verbose=false); enum VerifyMesgModes { _verify_quietly = 0, diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -47,6 +48,9 @@ // Static arena for symbols that are not deallocated Arena* SymbolTable::_arena = NULL; bool SymbolTable::_needs_rehashing = false; +bool SymbolTable::_lookup_shared_first = false; + +CompactHashtable SymbolTable::_shared_table; Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { assert (len <= Symbol::max_length(), "should be checked by caller"); @@ -186,8 +190,8 @@ // Lookup a symbol in a bucket. -Symbol* SymbolTable::lookup(int index, const char* name, - int len, unsigned int hash) { +Symbol* SymbolTable::lookup_dynamic(int index, const char* name, + int len, unsigned int hash) { int count = 0; for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { count++; // count all entries in this bucket, not just ones with same hash @@ -207,6 +211,34 @@ return NULL; } +Symbol* SymbolTable::lookup_shared(const char* name, + int len, unsigned int hash) { + return _shared_table.lookup(name, hash, len); +} + +Symbol* SymbolTable::lookup(int index, const char* name, + int len, unsigned int hash) { + Symbol* sym; + if (_lookup_shared_first) { + sym = lookup_shared(name, len, hash); + if (sym != NULL) { + return sym; + } + _lookup_shared_first = false; + return lookup_dynamic(index, name, len, hash); + } else { + sym = lookup_dynamic(index, name, len, hash); + if (sym != NULL) { + return sym; + } + sym = lookup_shared(name, len, hash); + if (sym != NULL) { + _lookup_shared_first = true; + } + return sym; + } +} + // Pick hashing algorithm. unsigned int SymbolTable::hash_symbol(const char* s, int len) { return use_alternate_hashcode() ? @@ -483,10 +515,56 @@ } } -void SymbolTable::dump(outputStream* st) { - the_table()->dump_table(st, "SymbolTable"); +void SymbolTable::dump(outputStream* st, bool verbose) { + if (!verbose) { + the_table()->dump_table(st, "SymbolTable"); + } else { + st->print_cr("VERSION: 1.0"); + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + Symbol* s = (Symbol*)(p->literal()); + const char* utf8_string = (const char*)s->bytes(); + int utf8_length = s->utf8_length(); + st->print("%d %d: ", utf8_length, s->refcount()); + HashtableTextDump::put_utf8(st, utf8_string, utf8_length); + st->cr(); + } + } + } } +bool SymbolTable::copy_compact_table(char** top, char*end) { +#if INCLUDE_CDS + CompactHashtableWriter ch_table("symbol", the_table()->number_of_entries(), + &MetaspaceShared::stats()->symbol); + if (*top + ch_table.get_required_bytes() > end) { + // not enough space left + return false; + } + + for (int i = 0; i < the_table()->table_size(); ++i) { + HashtableEntry* p = the_table()->bucket(i); + for ( ; p != NULL; p = p->next()) { + Symbol* s = (Symbol*)(p->literal()); + unsigned int fixed_hash = hash_symbol((char*)s->bytes(), s->utf8_length()); + assert(fixed_hash == p->hash(), "must not rehash during dumping"); + ch_table.add(fixed_hash, s); + } + } + + char* old_top = *top; + ch_table.dump(top, end); + + *top = (char*)align_pointer_up(*top, sizeof(void*)); +#endif + return true; +} + +const char* SymbolTable::init_shared_table(const char* buffer) { + const char* end = _shared_table.init(buffer); + return (const char*)align_pointer_up(end, sizeof(void*)); +} //--------------------------------------------------------------------------- // Non-product code @@ -574,3 +652,29 @@ } } #endif // PRODUCT + + +// Utility for dumping symbols +SymboltableDCmd::SymboltableDCmd(outputStream* output, bool heap) : + DCmdWithParser(output, heap), + _verbose("-verbose", "Dump the content of each symbol in the table", + "BOOLEAN", false, "false") { + _dcmdparser.add_dcmd_option(&_verbose); +} + +void SymboltableDCmd::execute(DCmdSource source, TRAPS) { + VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpSymbols, + _verbose.value()); + VMThread::execute(&dumper); +} + +int SymboltableDCmd::num_arguments() { + ResourceMark rm; + SymboltableDCmd* dcmd = new SymboltableDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/symbolTable.hpp --- a/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -73,6 +73,8 @@ operator Symbol*() { return _temp; } }; +template class CompactHashtable; + class SymbolTable : public RehashableHashtable { friend class VMStructs; friend class ClassFileParser; @@ -83,11 +85,15 @@ // Set if one bucket is out of balance due to hash algorithm deficiency static bool _needs_rehashing; + static bool _lookup_shared_first; // For statistics static int _symbols_removed; static int _symbols_counted; + // shared symbol table. + static CompactHashtable _shared_table; + Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F // Adding elements @@ -106,6 +112,8 @@ add(loader_data, cp, names_count, name, lengths, cp_indices, hashValues, THREAD); } + static Symbol* lookup_shared(const char* name, int len, unsigned int hash); + Symbol* lookup_dynamic(int index, const char* name, int len, unsigned int hash); Symbol* lookup(int index, const char* name, int len, unsigned int hash); SymbolTable() @@ -144,20 +152,6 @@ initialize_symbols(symbol_alloc_arena_size); } - static void create_table(HashtableBucket* t, int length, - int number_of_entries) { - assert(_the_table == NULL, "One symbol table allowed."); - - // If CDS archive used a different symbol table size, use that size instead - // which is better than giving an error. - SymbolTableSize = length/bucket_size(); - - _the_table = new SymbolTable(t, number_of_entries); - // if CDS give symbol table a default arena size since most symbols - // are already allocated in the shared misc section. - initialize_symbols(); - } - static unsigned int hash_symbol(const char* s, int len); static Symbol* lookup(const char* name, int len, TRAPS); @@ -230,18 +224,12 @@ // Debugging static void verify(); - static void dump(outputStream* st); + static void dump(outputStream* st, bool verbose=false); + static void read(const char* filename, TRAPS); // Sharing - static void copy_buckets(char** top, char*end) { - the_table()->Hashtable::copy_buckets(top, end); - } - static void copy_table(char** top, char*end) { - the_table()->Hashtable::copy_table(top, end); - } - static void reverse(void* boundary = NULL) { - the_table()->Hashtable::reverse(boundary); - } + static bool copy_compact_table(char** top, char* end); + static const char* init_shared_table(const char* buffer); // Rehash the symbol table if it gets out of balance static void rehash_table(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/interpreter.hpp" @@ -1627,7 +1628,7 @@ // Note: must be done *after* linking k into the hierarchy (was bug 12/9/97) // Also, first reinitialize vtable because it may have gotten out of synch // while the new class wasn't connected to the class hierarchy. - Universe::flush_dependents_on(k); + CodeCache::flush_dependents_on(k); } // ---------------------------------------------------------------------------- diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -2477,8 +2477,7 @@ // of the current class. VerificationType objectref_type = new_class_type; if (name_in_supers(ref_class_type.name(), current_class())) { - Klass* ref_klass = load_class( - ref_class_type.name(), CHECK_VERIFY(this)); + Klass* ref_klass = load_class(ref_class_type.name(), CHECK); Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method( vmSymbols::object_initializer_name(), cp->signature_ref_at(bcs->get_index_u2()), diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/code/codeCache.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1005,6 +1005,117 @@ } } +// Flushes compiled methods dependent on dependee. +void CodeCache::flush_dependents_on(instanceKlassHandle dependee) { + assert_lock_strong(Compile_lock); + + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + KlassDepChange changes(dependee); + + // Compute the dependent nmethods + if (mark_for_deoptimization(changes) > 0) { + // At least one nmethod has been marked for deoptimization + VM_Deoptimize op; + VMThread::execute(&op); + } +} + +// Flushes compiled methods dependent on a particular CallSite +// instance when its target is different than the given MethodHandle. +void CodeCache::flush_dependents_on(Handle call_site, Handle method_handle) { + assert_lock_strong(Compile_lock); + + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + CallSiteDepChange changes(call_site(), method_handle()); + + // Compute the dependent nmethods that have a reference to a + // CallSite object. We use InstanceKlass::mark_dependent_nmethod + // directly instead of CodeCache::mark_for_deoptimization because we + // want dependents on the call site class only not all classes in + // the ContextStream. + int marked = 0; + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass()); + marked = call_site_klass->mark_dependent_nmethods(changes); + } + if (marked > 0) { + // At least one nmethod has been marked for deoptimization + VM_Deoptimize op; + VMThread::execute(&op); + } +} + +#ifdef HOTSWAP +// Flushes compiled methods dependent on dependee in the evolutionary sense +void CodeCache::flush_evol_dependents_on(instanceKlassHandle ev_k_h) { + // --- Compile_lock is not held. However we are at a safepoint. + assert_locked_or_safepoint(Compile_lock); + if (number_of_nmethods_with_dependencies() == 0) return; + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped during the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + // Compute the dependent nmethods + if (mark_for_evol_deoptimization(ev_k_h) > 0) { + // At least one nmethod has been marked for deoptimization + + // All this already happens inside a VM_Operation, so we'll do all the work here. + // Stuff copied from VM_Deoptimize and modified slightly. + + // We do not want any GCs to happen while we are in the middle of this VM operation + ResourceMark rm; + DeoptimizationMarker dm; + + // Deoptimize all activations depending on marked nmethods + Deoptimization::deoptimize_dependents(); + + // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) + make_marked_nmethods_not_entrant(); + } +} +#endif // HOTSWAP + + +// Flushes compiled methods dependent on dependee +void CodeCache::flush_dependents_on_method(methodHandle m_h) { + // --- Compile_lock is not held. However we are at a safepoint. + assert_locked_or_safepoint(Compile_lock); + + // CodeCache can only be updated by a thread_in_VM and they will all be + // stopped dring the safepoint so CodeCache will be safe to update without + // holding the CodeCache_lock. + + // Compute the dependent nmethods + if (mark_for_deoptimization(m_h()) > 0) { + // At least one nmethod has been marked for deoptimization + + // All this already happens inside a VM_Operation, so we'll do all the work here. + // Stuff copied from VM_Deoptimize and modified slightly. + + // We do not want any GCs to happen while we are in the middle of this VM operation + ResourceMark rm; + DeoptimizationMarker dm; + + // Deoptimize all activations depending on marked nmethods + Deoptimization::deoptimize_dependents(); + + // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) + make_marked_nmethods_not_entrant(); + } +} + void CodeCache::verify() { assert_locked_or_safepoint(CodeCache_lock); FOR_ALL_HEAPS(heap) { diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/code/codeCache.hpp --- a/hotspot/src/share/vm/code/codeCache.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/code/codeCache.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,16 +209,28 @@ static void verify_icholder_relocations(); // Deoptimization + private: static int mark_for_deoptimization(DepChange& changes); #ifdef HOTSWAP static int mark_for_evol_deoptimization(instanceKlassHandle dependee); #endif // HOTSWAP + public: static void mark_all_nmethods_for_deoptimization(); static int mark_for_deoptimization(Method* dependee); static void make_marked_nmethods_zombies(); static void make_marked_nmethods_not_entrant(); + // Flushing and deoptimization + static void flush_dependents_on(instanceKlassHandle dependee); + static void flush_dependents_on(Handle call_site, Handle method_handle); +#ifdef HOTSWAP + // Flushing and deoptimization in case of evolution + static void flush_evol_dependents_on(instanceKlassHandle dependee); +#endif // HOTSWAP + // Support for fullspeed debugging + static void flush_dependents_on_method(methodHandle dependee); + // tells how many nmethods have dependencies static int number_of_nmethods_with_dependencies(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -99,8 +99,8 @@ } if (ResizePLAB) { - _g1h->_survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); - _g1h->_old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); + _g1h->alloc_buffer_stats(InCSetState::Young)->adjust_desired_plab_sz(no_of_gc_workers); + _g1h->alloc_buffer_stats(InCSetState::Old)->adjust_desired_plab_sz(no_of_gc_workers); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -2068,7 +2068,7 @@ } void G1CollectedHeap::clear_humongous_is_live_table() { - guarantee(G1ReclaimDeadHumongousObjectsAtYoungGC, "Should only be called if true"); + guarantee(G1EagerReclaimHumongousObjects, "Should only be called if true"); _humongous_is_live.clear(); } @@ -3485,8 +3485,24 @@ private: size_t _total_humongous; size_t _candidate_humongous; + + DirtyCardQueue _dcq; + + bool humongous_region_is_candidate(uint index) { + HeapRegion* region = G1CollectedHeap::heap()->region_at(index); + assert(region->is_starts_humongous(), "Must start a humongous object"); + HeapRegionRemSet* const rset = region->rem_set(); + bool const allow_stale_refs = G1EagerReclaimHumongousObjectsWithStaleRefs; + return !oop(region->bottom())->is_objArray() && + ((allow_stale_refs && rset->occupancy_less_or_equal_than(G1RSetSparseRegionEntries)) || + (!allow_stale_refs && rset->is_empty())); + } + public: - RegisterHumongousWithInCSetFastTestClosure() : _total_humongous(0), _candidate_humongous(0) { + RegisterHumongousWithInCSetFastTestClosure() + : _total_humongous(0), + _candidate_humongous(0), + _dcq(&JavaThread::dirty_card_queue_set()) { } virtual bool doHeapRegion(HeapRegion* r) { @@ -3496,11 +3512,29 @@ G1CollectedHeap* g1h = G1CollectedHeap::heap(); uint region_idx = r->hrm_index(); - bool is_candidate = !g1h->humongous_region_is_always_live(region_idx); - // Is_candidate already filters out humongous regions with some remembered set. - // This will not lead to humongous object that we mistakenly keep alive because - // during young collection the remembered sets will only be added to. + bool is_candidate = humongous_region_is_candidate(region_idx); + // Is_candidate already filters out humongous object with large remembered sets. + // If we have a humongous object with a few remembered sets, we simply flush these + // remembered set entries into the DCQS. That will result in automatic + // re-evaluation of their remembered set entries during the following evacuation + // phase. if (is_candidate) { + if (!r->rem_set()->is_empty()) { + guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries), + "Found a not-small remembered set here. This is inconsistent with previous assumptions."); + G1SATBCardTableLoggingModRefBS* bs = g1h->g1_barrier_set(); + HeapRegionRemSetIterator hrrs(r->rem_set()); + size_t card_index; + while (hrrs.has_next(card_index)) { + jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index); + if (*card_ptr != CardTableModRefBS::dirty_card_val()) { + *card_ptr = CardTableModRefBS::dirty_card_val(); + _dcq.enqueue(card_ptr); + } + } + r->rem_set()->clear_locked(); + } + assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty."); g1h->register_humongous_region_with_in_cset_fast_test(region_idx); _candidate_humongous++; } @@ -3511,23 +3545,32 @@ size_t total_humongous() const { return _total_humongous; } size_t candidate_humongous() const { return _candidate_humongous; } + + void flush_rem_set_entries() { _dcq.flush(); } }; void G1CollectedHeap::register_humongous_regions_with_in_cset_fast_test() { - if (!G1ReclaimDeadHumongousObjectsAtYoungGC) { - g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0, 0); + if (!G1EagerReclaimHumongousObjects) { + g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(0.0, 0, 0); return; } + double time = os::elapsed_counter(); RegisterHumongousWithInCSetFastTestClosure cl; heap_region_iterate(&cl); - g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(cl.total_humongous(), + + time = ((double)(os::elapsed_counter() - time) / os::elapsed_frequency()) * 1000.0; + g1_policy()->phase_times()->record_fast_reclaim_humongous_stats(time, + cl.total_humongous(), cl.candidate_humongous()); _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0; - if (_has_humongous_reclaim_candidates || G1TraceReclaimDeadHumongousObjectsAtYoungGC) { + if (_has_humongous_reclaim_candidates || G1TraceEagerReclaimHumongousObjects) { clear_humongous_is_live_table(); } + + // Finally flush all remembered set entries to re-check into the global DCQS. + cl.flush_rem_set_entries(); } void @@ -6140,22 +6183,20 @@ // are completely up-to-date wrt to references to the humongous object. // // Other implementation considerations: - // - never consider object arrays: while they are a valid target, they have not - // been observed to be used as temporary objects. - // - they would also pose considerable effort for cleaning up the the remembered - // sets. - // While this cleanup is not strictly necessary to be done (or done instantly), - // given that their occurrence is very low, this saves us this additional - // complexity. + // - never consider object arrays at this time because they would pose + // considerable effort for cleaning up the the remembered sets. This is + // required because stale remembered sets might reference locations that + // are currently allocated into. uint region_idx = r->hrm_index(); if (g1h->humongous_is_live(region_idx) || g1h->humongous_region_is_always_live(region_idx)) { - if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) { - gclog_or_tty->print_cr("Live humongous %d region %d size "SIZE_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", - r->is_humongous(), + if (G1TraceEagerReclaimHumongousObjects) { + gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", region_idx, obj->size()*HeapWordSize, + r->bottom(), + r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), next_bitmap->isMarked(r->bottom()), @@ -6171,12 +6212,11 @@ err_msg("Eagerly reclaiming object arrays is not supported, but the object "PTR_FORMAT" is.", r->bottom())); - if (G1TraceReclaimDeadHumongousObjectsAtYoungGC) { - gclog_or_tty->print_cr("Reclaim humongous region %d size "SIZE_FORMAT" start "PTR_FORMAT" region %d length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", - r->is_humongous(), + if (G1TraceEagerReclaimHumongousObjects) { + gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d live-other %d obj array %d", + region_idx, obj->size()*HeapWordSize, r->bottom(), - region_idx, r->region_num(), r->rem_set()->occupied(), r->rem_set()->strong_code_roots_list_length(), @@ -6213,8 +6253,8 @@ void G1CollectedHeap::eagerly_reclaim_humongous_regions() { assert_at_safepoint(true); - if (!G1ReclaimDeadHumongousObjectsAtYoungGC || - (!_has_humongous_reclaim_candidates && !G1TraceReclaimDeadHumongousObjectsAtYoungGC)) { + if (!G1EagerReclaimHumongousObjects || + (!_has_humongous_reclaim_candidates && !G1TraceEagerReclaimHumongousObjects)) { g1_policy()->phase_times()->record_fast_reclaim_humongous_time_ms(0.0, 0); return; } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -186,32 +186,14 @@ friend class SurvivorGCAllocRegion; friend class OldGCAllocRegion; friend class G1Allocator; - friend class G1DefaultAllocator; - friend class G1ResManAllocator; // Closures used in implementation. - template - friend class G1ParCopyClosure; - friend class G1IsAliveClosure; - friend class G1EvacuateFollowersClosure; friend class G1ParScanThreadState; - friend class G1ParScanClosureSuper; - friend class G1ParEvacuateFollowersClosure; friend class G1ParTask; friend class G1ParGCAllocator; - friend class G1DefaultParGCAllocator; - friend class G1FreeGarbageRegionClosure; - friend class RefineCardTableEntryClosure; friend class G1PrepareCompactClosure; - friend class RegionSorter; - friend class RegionResetter; - friend class CountRCClosure; - friend class EvacPopObjClosure; - friend class G1ParCleanupCTTask; - friend class G1FreeHumongousRegionClosure; // Other related classes. - friend class G1MarkSweep; friend class HeapRegionClaimer; // Testing classes. @@ -659,6 +641,9 @@ // Returns whether the given region (which must be a humongous (start) region) // is to be considered conservatively live regardless of any other conditions. bool humongous_region_is_always_live(uint index); + // Returns whether the given region (which must be a humongous (start) region) + // is considered a candidate for eager reclamation. + bool humongous_region_is_candidate(uint index); // Register the given region to be part of the collection set. inline void register_humongous_region_with_in_cset_fast_test(uint index); // Register regions with humongous objects (actually on the start region) in diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -344,11 +344,14 @@ _last_redirty_logged_cards_time_ms.print(3, "Parallel Redirty"); _last_redirty_logged_cards_processed_cards.print(3, "Redirtied Cards"); } - if (G1ReclaimDeadHumongousObjectsAtYoungGC) { - print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); + if (G1EagerReclaimHumongousObjects) { + print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms); if (G1Log::finest()) { print_stats(3, "Humongous Total", _cur_fast_reclaim_humongous_total); print_stats(3, "Humongous Candidate", _cur_fast_reclaim_humongous_candidates); + } + print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); + if (G1Log::finest()) { print_stats(3, "Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -157,6 +157,7 @@ double _recorded_non_young_free_cset_time_ms; double _cur_fast_reclaim_humongous_time_ms; + double _cur_fast_reclaim_humongous_register_time_ms; size_t _cur_fast_reclaim_humongous_total; size_t _cur_fast_reclaim_humongous_candidates; size_t _cur_fast_reclaim_humongous_reclaimed; @@ -283,7 +284,8 @@ _recorded_non_young_free_cset_time_ms = time_ms; } - void record_fast_reclaim_humongous_stats(size_t total, size_t candidates) { + void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) { + _cur_fast_reclaim_humongous_register_time_ms = time_ms; _cur_fast_reclaim_humongous_total = total; _cur_fast_reclaim_humongous_candidates = candidates; } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -270,10 +270,14 @@ product(uintx, G1MixedGCCountTarget, 8, \ "The target number of mixed GCs after a marking cycle.") \ \ - experimental(bool, G1ReclaimDeadHumongousObjectsAtYoungGC, true, \ + experimental(bool, G1EagerReclaimHumongousObjects, true, \ "Try to reclaim dead large objects at every young GC.") \ \ - experimental(bool, G1TraceReclaimDeadHumongousObjectsAtYoungGC, false, \ + experimental(bool, G1EagerReclaimHumongousObjectsWithStaleRefs, true, \ + "Try to reclaim dead large objects that have a few stale " \ + "references at every young GC.") \ + \ + experimental(bool, G1TraceEagerReclaimHumongousObjects, false, \ "Print some information about large object liveness " \ "at every young GC.") \ \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -681,6 +681,18 @@ clear_fcc(); } +bool OtherRegionsTable::occupancy_less_or_equal_than(size_t limit) const { + if (limit <= (size_t)G1RSetSparseRegionEntries) { + return occ_coarse() == 0 && _first_all_fine_prts == NULL && occ_sparse() <= limit; + } else { + // Current uses of this method may only use values less than G1RSetSparseRegionEntries + // for the limit. The solution, comparing against occupied() would be too slow + // at this time. + Unimplemented(); + return false; + } +} + bool OtherRegionsTable::is_empty() const { return occ_sparse() == 0 && occ_coarse() == 0 && _first_all_fine_prts == NULL; } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -183,6 +183,10 @@ // Returns whether the remembered set contains the given reference. bool contains_reference(OopOrNarrowOopStar from) const; + // Returns whether this remembered set (and all sub-sets) have an occupancy + // that is less or equal than the given occupancy. + bool occupancy_less_or_equal_than(size_t limit) const; + // Removes any entries shown by the given bitmaps to contain only dead // objects. Not thread safe. // Set bits in the bitmaps indicate that the given region or card is live. @@ -261,6 +265,10 @@ return (strong_code_roots_list_length() == 0) && _other_regions.is_empty(); } + bool occupancy_less_or_equal_than(size_t occ) const { + return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ); + } + size_t occupied() { MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); return occupied_locked(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -422,7 +422,7 @@ bool large_pages = false; // No large pages when dumping the CDS archive. char* shared_base = (char*)align_ptr_up((char*)SharedBaseAddress, Metaspace::reserve_alignment()); - _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages, shared_base, 0); + _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages, shared_base); if (_rs.is_reserved()) { assert(shared_base == 0 || _rs.base() == shared_base, "should match"); } else { @@ -3025,7 +3025,7 @@ ReservedSpace metaspace_rs = ReservedSpace(compressed_class_space_size(), _reserve_alignment, large_pages, - requested_addr, 0); + requested_addr); if (!metaspace_rs.is_reserved()) { #if INCLUDE_CDS if (UseSharedSpaces) { @@ -3039,7 +3039,7 @@ can_use_cds_with_metaspace_addr(addr + increment, cds_base)) { addr = addr + increment; metaspace_rs = ReservedSpace(compressed_class_space_size(), - _reserve_alignment, large_pages, addr, 0); + _reserve_alignment, large_pages, addr); } } #endif diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/memory/metaspaceShared.cpp --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -48,6 +48,8 @@ ReservedSpace* MetaspaceShared::_shared_rs = NULL; +MetaspaceSharedStats MetaspaceShared::_stats; + bool MetaspaceShared::_link_classes_made_progress; bool MetaspaceShared::_check_classes_made_progress; bool MetaspaceShared::_has_error_classes; @@ -259,7 +261,7 @@ #define SHAREDSPACE_OBJ_TYPES_DO(f) \ METASPACE_OBJ_TYPES_DO(f) \ f(SymbolHashentry) \ - f(SymbolBuckets) \ + f(SymbolBucket) \ f(Other) #define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type, @@ -315,18 +317,16 @@ int other_bytes = md_all + mc_all; // Calculate size of data that was not allocated by Metaspace::allocate() - int symbol_count = _counts[RO][MetaspaceObj::SymbolType]; - int symhash_bytes = symbol_count * sizeof (HashtableEntry); - int symbuck_count = SymbolTable::the_table()->table_size(); - int symbuck_bytes = symbuck_count * sizeof(HashtableBucket); + MetaspaceSharedStats *stats = MetaspaceShared::stats(); - _counts[RW][SymbolHashentryType] = symbol_count; - _bytes [RW][SymbolHashentryType] = symhash_bytes; - other_bytes -= symhash_bytes; + // symbols + _counts[RW][SymbolHashentryType] = stats->symbol.hashentry_count; + _bytes [RW][SymbolHashentryType] = stats->symbol.hashentry_bytes; + other_bytes -= stats->symbol.hashentry_bytes; - _counts[RW][SymbolBucketsType] = symbuck_count; - _bytes [RW][SymbolBucketsType] = symbuck_bytes; - other_bytes -= symbuck_bytes; + _counts[RW][SymbolBucketType] = stats->symbol.bucket_count; + _bytes [RW][SymbolBucketType] = stats->symbol.bucket_bytes; + other_bytes -= stats->symbol.bucket_bytes; // TODO: count things like dictionary, vtable, etc _bytes[RW][OtherType] = other_bytes; @@ -424,6 +424,13 @@ VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } void doit(); // outline because gdb sucks + +private: + void handle_misc_data_space_failure(bool success) { + if (!success) { + report_out_of_shared_space(SharedMiscData); + } + } }; // class VM_PopulateDumpSharedSpace @@ -517,9 +524,8 @@ // buckets first [read-write], then copy the linked lists of entries // [read-only]. - SymbolTable::reverse(md_top); NOT_PRODUCT(SymbolTable::verify()); - SymbolTable::copy_buckets(&md_top, md_end); + handle_misc_data_space_failure(SymbolTable::copy_compact_table(&md_top, md_end)); SystemDictionary::reverse(); SystemDictionary::copy_buckets(&md_top, md_end); @@ -528,7 +534,6 @@ ClassLoader::copy_package_info_buckets(&md_top, md_end); ClassLoader::verify(); - SymbolTable::copy_table(&md_top, md_end); SystemDictionary::copy_table(&md_top, md_end); ClassLoader::verify(); ClassLoader::copy_package_info_table(&md_top, md_end); @@ -1000,17 +1005,12 @@ buffer += sizeof(intptr_t); buffer += vtable_size; - // Create the symbol table using the bucket array at this spot in the - // misc data space. Since the symbol table is often modified, this - // region (of mapped pages) will be copy-on-write. + // Create the shared symbol table using the bucket array at this spot in the + // misc data space. (Todo: move this to read-only space. Currently + // this is mapped copy-on-write but will never be written into). - int symbolTableLen = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - int number_of_entries = *(intptr_t*)buffer; - buffer += sizeof(intptr_t); - SymbolTable::create_table((HashtableBucket*)buffer, symbolTableLen, - number_of_entries); - buffer += symbolTableLen; + buffer = (char*)SymbolTable::init_shared_table(buffer); + SymbolTable::create_table(); // Create the shared dictionary using the bucket array at this spot in // the misc data space. Since the shared dictionary table is never @@ -1019,7 +1019,7 @@ int sharedDictionaryLen = *(intptr_t*)buffer; buffer += sizeof(intptr_t); - number_of_entries = *(intptr_t*)buffer; + int number_of_entries = *(intptr_t*)buffer; buffer += sizeof(intptr_t); SystemDictionary::set_shared_dictionary((HashtableBucket*)buffer, sharedDictionaryLen, @@ -1041,18 +1041,10 @@ ClassLoader::verify(); // The following data in the shared misc data region are the linked - // list elements (HashtableEntry objects) for the symbol table, string - // table, and shared dictionary. The heap objects referred to by the - // symbol table, string table, and shared dictionary are permanent and - // unmovable. Since new entries added to the string and symbol tables - // are always added at the beginning of the linked lists, THESE LINKED - // LIST ELEMENTS ARE READ-ONLY. + // list elements (HashtableEntry objects) for the shared dictionary + // and package info table. - int len = *(intptr_t*)buffer; // skip over symbol table entries - buffer += sizeof(intptr_t); - buffer += len; - - len = *(intptr_t*)buffer; // skip over shared dictionary entries + int len = *(intptr_t*)buffer; // skip over shared dictionary entries buffer += sizeof(intptr_t); buffer += len; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/memory/metaspaceShared.hpp --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -24,6 +24,7 @@ #ifndef SHARE_VM_MEMORY_METASPACE_SHARED_HPP #define SHARE_VM_MEMORY_METASPACE_SHARED_HPP +#include "classfile/compactHashtable.hpp" #include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "runtime/virtualspace.hpp" @@ -45,12 +46,21 @@ class FileMapInfo; +class MetaspaceSharedStats VALUE_OBJ_CLASS_SPEC { +public: + MetaspaceSharedStats() { + memset(this, 0, sizeof(*this)); + } + CompactHashtableStats symbol; +}; + // Class Data Sharing Support class MetaspaceShared : AllStatic { // CDS support static ReservedSpace* _shared_rs; static int _max_alignment; + static MetaspaceSharedStats _stats; static bool _link_classes_made_progress; static bool _check_classes_made_progress; static bool _has_error_classes; @@ -123,6 +133,10 @@ char** mc_top, char* mc_end); static void serialize(SerializeClosure* sc); + static MetaspaceSharedStats* stats() { + return &_stats; + } + // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private if // sharing is enabled. Simply returns true if sharing is not enabled diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/memory/universe.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -694,103 +694,6 @@ // NarrowOopHeapBaseMin + heap_size < 32Gb // HeapBased - Use compressed oops with heap base + encoding. -// 4Gb -static const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); -// 32Gb -// OopEncodingHeapMax == UnscaledOopHeapMax << LogMinObjAlignmentInBytes; - -char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) { - assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be"); - assert(is_size_aligned((size_t)UnscaledOopHeapMax, alignment), "Must be"); - assert(is_size_aligned(heap_size, alignment), "Must be"); - - uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment); - - size_t base = 0; -#ifdef _LP64 - if (UseCompressedOops) { - assert(mode == UnscaledNarrowOop || - mode == ZeroBasedNarrowOop || - mode == HeapBasedNarrowOop, "mode is invalid"); - const size_t total_size = heap_size + heap_base_min_address_aligned; - // Return specified base for the first request. - if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { - base = heap_base_min_address_aligned; - - // If the total size is small enough to allow UnscaledNarrowOop then - // just use UnscaledNarrowOop. - } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) { - if ((total_size <= UnscaledOopHeapMax) && (mode == UnscaledNarrowOop) && - (Universe::narrow_oop_shift() == 0)) { - // Use 32-bits oops without encoding and - // place heap's top on the 4Gb boundary - base = (UnscaledOopHeapMax - heap_size); - } else { - // Can't reserve with NarrowOopShift == 0 - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - - if (mode == UnscaledNarrowOop || - mode == ZeroBasedNarrowOop && total_size <= UnscaledOopHeapMax) { - - // Use zero based compressed oops with encoding and - // place heap's top on the 32Gb boundary in case - // total_size > 4Gb or failed to reserve below 4Gb. - uint64_t heap_top = OopEncodingHeapMax; - - // For small heaps, save some space for compressed class pointer - // space so it can be decoded with no base. - if (UseCompressedClassPointers && !UseSharedSpaces && - OopEncodingHeapMax <= 32*G) { - - uint64_t class_space = align_size_up(CompressedClassSpaceSize, alignment); - assert(is_size_aligned((size_t)OopEncodingHeapMax-class_space, - alignment), "difference must be aligned too"); - uint64_t new_top = OopEncodingHeapMax-class_space; - - if (total_size <= new_top) { - heap_top = new_top; - } - } - - // Align base to the adjusted top of the heap - base = heap_top - heap_size; - } - } - } else { - // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or - // HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb. - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - } - - // Set narrow_oop_base and narrow_oop_use_implicit_null_checks - // used in ReservedHeapSpace() constructors. - // The final values will be set in initialize_heap() below. - if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) { - // Use zero based compressed oops - Universe::set_narrow_oop_base(NULL); - // Don't need guard page for implicit checks in indexed - // addressing mode with zero based Compressed Oops. - Universe::set_narrow_oop_use_implicit_null_checks(true); - } else { - // Set to a non-NULL value so the ReservedSpace ctor computes - // the correct no-access prefix. - // The final value will be set in initialize_heap() below. - Universe::set_narrow_oop_base((address)UnscaledOopHeapMax); -#if defined(_WIN64) || defined(AIX) - if (UseLargePages) { - // Cannot allocate guard pages for implicit checks in indexed - // addressing mode when large pages are specified on windows. - Universe::set_narrow_oop_use_implicit_null_checks(false); - } -#endif // _WIN64 - } - } -#endif - - assert(is_ptr_aligned((char*)base, alignment), "Must be"); - return (char*)base; // also return NULL (don't care) for 32-bit VM -} - jint Universe::initialize_heap() { if (UseParallelGC) { @@ -844,30 +747,13 @@ // See needs_explicit_null_check. // Only set the heap base for compressed oops because it indicates // compressed oops for pstack code. - if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) { - // Can't reserve heap below 32Gb. - // keep the Universe::narrow_oop_base() set in Universe::reserve_heap() + if ((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) { + // Didn't reserve heap below 4Gb. Must shift. Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); -#ifdef AIX - // There is no protected page before the heap. This assures all oops - // are decoded so that NULL is preserved, so this page will not be accessed. - Universe::set_narrow_oop_use_implicit_null_checks(false); -#endif - } else { + } + if ((uint64_t)Universe::heap()->reserved_region().end() <= OopEncodingHeapMax) { + // Did reserve heap below 32Gb. Can use base == 0; Universe::set_narrow_oop_base(0); -#ifdef _WIN64 - if (!Universe::narrow_oop_use_implicit_null_checks()) { - // Don't need guard page for implicit checks in indexed addressing - // mode with zero based Compressed Oops. - Universe::set_narrow_oop_use_implicit_null_checks(true); - } -#endif // _WIN64 - if((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) { - // Can't reserve heap below 4Gb. - Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); - } else { - Universe::set_narrow_oop_shift(0); - } } Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); @@ -875,6 +761,11 @@ if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { Universe::print_compressed_oops_mode(); } + + // Tell tests in which mode we run. + Arguments::PropertyList_add(new SystemProperty("java.vm.compressedOopsMode", + narrow_oop_mode_to_string(narrow_oop_mode()), + false)); } // Universe::narrow_oop_base() is one page below the heap. assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - @@ -903,22 +794,27 @@ tty->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); if (Universe::narrow_oop_base() != 0) { - tty->print(":" PTR_FORMAT, Universe::narrow_oop_base()); + tty->print(": " PTR_FORMAT, Universe::narrow_oop_base()); } if (Universe::narrow_oop_shift() != 0) { tty->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); } + if (!Universe::narrow_oop_use_implicit_null_checks()) { + tty->print(", no protected page in front of the heap"); + } + tty->cr(); tty->cr(); } -// Reserve the Java heap, which is now the same for all GCs. ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { + assert(alignment <= Arguments::conservative_max_heap_alignment(), err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT, alignment, Arguments::conservative_max_heap_alignment())); + size_t total_reserved = align_size_up(heap_size, alignment); assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), "heap size is too big for compressed oops"); @@ -928,46 +824,31 @@ || UseParallelGC || use_large_pages, "Wrong alignment to use large pages"); - char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop); - - ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, addr); + // Now create the space. + ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages); - if (UseCompressedOops) { - if (addr != NULL && !total_rs.is_reserved()) { - // Failed to reserve at specified address - the requested memory - // region is taken already, for example, by 'java' launcher. - // Try again to reserver heap higher. - addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::ZeroBasedNarrowOop); - - ReservedHeapSpace total_rs0(total_reserved, alignment, - use_large_pages, addr); + if (total_rs.is_reserved()) { + assert((total_reserved == total_rs.size()) && ((uintptr_t)total_rs.base() % alignment == 0), + "must be exactly of required size and alignment"); + // We are good. - if (addr != NULL && !total_rs0.is_reserved()) { - // Failed to reserve at specified address again - give up. - addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::HeapBasedNarrowOop); - assert(addr == NULL, ""); + if (UseCompressedOops) { + // Universe::initialize_heap() will reset this to NULL if unscaled + // or zero-based narrow oops are actually used. + // Else heap start and base MUST differ, so that NULL can be encoded nonambigous. + Universe::set_narrow_oop_base((address)total_rs.compressed_oop_base()); + } - ReservedHeapSpace total_rs1(total_reserved, alignment, - use_large_pages, addr); - total_rs = total_rs1; - } else { - total_rs = total_rs0; - } - } - } - - if (!total_rs.is_reserved()) { - vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K)); return total_rs; } - if (UseCompressedOops) { - // Universe::initialize_heap() will reset this to NULL if unscaled - // or zero-based narrow oops are actually used. - address base = (address)(total_rs.base() - os::vm_page_size()); - Universe::set_narrow_oop_base(base); - } - return total_rs; + vm_exit_during_initialization( + err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", + total_reserved/K)); + + // satisfy compiler + ShouldNotReachHere(); + return ReservedHeapSpace(0, 0, false); } @@ -985,6 +866,8 @@ return "32-bit"; case ZeroBasedNarrowOop: return "Zero based"; + case DisjointBaseNarrowOop: + return "Non-zero disjoint base"; case HeapBasedNarrowOop: return "Non-zero based"; } @@ -995,6 +878,10 @@ Universe::NARROW_OOP_MODE Universe::narrow_oop_mode() { + if (narrow_oop_base_disjoint()) { + return DisjointBaseNarrowOop; + } + if (narrow_oop_base() != 0) { return HeapBasedNarrowOop; } @@ -1176,9 +1063,7 @@ MemoryService::set_universe_heap(Universe::_collectedHeap); #if INCLUDE_CDS - if (UseSharedSpaces) { - SharedClassUtil::initialize(CHECK_false); - } + SharedClassUtil::initialize(CHECK_false); #endif return true; } @@ -1189,119 +1074,6 @@ } -// %%% The Universe::flush_foo methods belong in CodeCache. - -// Flushes compiled methods dependent on dependee. -void Universe::flush_dependents_on(instanceKlassHandle dependee) { - assert_lock_strong(Compile_lock); - - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - KlassDepChange changes(dependee); - - // Compute the dependent nmethods - if (CodeCache::mark_for_deoptimization(changes) > 0) { - // At least one nmethod has been marked for deoptimization - VM_Deoptimize op; - VMThread::execute(&op); - } -} - -// Flushes compiled methods dependent on a particular CallSite -// instance when its target is different than the given MethodHandle. -void Universe::flush_dependents_on(Handle call_site, Handle method_handle) { - assert_lock_strong(Compile_lock); - - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - CallSiteDepChange changes(call_site(), method_handle()); - - // Compute the dependent nmethods that have a reference to a - // CallSite object. We use InstanceKlass::mark_dependent_nmethod - // directly instead of CodeCache::mark_for_deoptimization because we - // want dependents on the call site class only not all classes in - // the ContextStream. - int marked = 0; - { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - InstanceKlass* call_site_klass = InstanceKlass::cast(call_site->klass()); - marked = call_site_klass->mark_dependent_nmethods(changes); - } - if (marked > 0) { - // At least one nmethod has been marked for deoptimization - VM_Deoptimize op; - VMThread::execute(&op); - } -} - -#ifdef HOTSWAP -// Flushes compiled methods dependent on dependee in the evolutionary sense -void Universe::flush_evol_dependents_on(instanceKlassHandle ev_k_h) { - // --- Compile_lock is not held. However we are at a safepoint. - assert_locked_or_safepoint(Compile_lock); - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped during the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - // Compute the dependent nmethods - if (CodeCache::mark_for_evol_deoptimization(ev_k_h) > 0) { - // At least one nmethod has been marked for deoptimization - - // All this already happens inside a VM_Operation, so we'll do all the work here. - // Stuff copied from VM_Deoptimize and modified slightly. - - // We do not want any GCs to happen while we are in the middle of this VM operation - ResourceMark rm; - DeoptimizationMarker dm; - - // Deoptimize all activations depending on marked nmethods - Deoptimization::deoptimize_dependents(); - - // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) - CodeCache::make_marked_nmethods_not_entrant(); - } -} -#endif // HOTSWAP - - -// Flushes compiled methods dependent on dependee -void Universe::flush_dependents_on_method(methodHandle m_h) { - // --- Compile_lock is not held. However we are at a safepoint. - assert_locked_or_safepoint(Compile_lock); - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped dring the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - - // Compute the dependent nmethods - if (CodeCache::mark_for_deoptimization(m_h()) > 0) { - // At least one nmethod has been marked for deoptimization - - // All this already happens inside a VM_Operation, so we'll do all the work here. - // Stuff copied from VM_Deoptimize and modified slightly. - - // We do not want any GCs to happen while we are in the middle of this VM operation - ResourceMark rm; - DeoptimizationMarker dm; - - // Deoptimize all activations depending on marked nmethods - Deoptimization::deoptimize_dependents(); - - // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) - CodeCache::make_marked_nmethods_not_entrant(); - } -} - void Universe::print() { print_on(gclog_or_tty); } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/memory/universe.hpp --- a/hotspot/src/share/vm/memory/universe.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/memory/universe.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,8 +102,8 @@ friend class MarkSweep; friend class oopDesc; friend class ClassLoader; - friend class Arguments; friend class SystemDictionary; + friend class ReservedHeapSpace; friend class VMStructs; friend class VM_PopulateDumpSharedSpace; friend class Metaspace; @@ -351,17 +351,40 @@ // NarrowOopHeapBaseMin + heap_size < 4Gb // 1 - Use zero based compressed oops with encoding when // NarrowOopHeapBaseMin + heap_size < 32Gb - // 2 - Use compressed oops with heap base + encoding. + // 2 - Use compressed oops with disjoint heap base if + // base is 32G-aligned and base > 0. This allows certain + // optimizations in encoding/decoding. + // Disjoint: Bits used in base are disjoint from bits used + // for oops ==> oop = (cOop << 3) | base. One can disjoint + // the bits of an oop into base and compressed oop. + // 3 - Use compressed oops with heap base + encoding. enum NARROW_OOP_MODE { UnscaledNarrowOop = 0, ZeroBasedNarrowOop = 1, - HeapBasedNarrowOop = 2 + DisjointBaseNarrowOop = 2, + HeapBasedNarrowOop = 3, + AnyNarrowOopMode = 4 }; static NARROW_OOP_MODE narrow_oop_mode(); static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode); static char* preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode); static char* preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode); - static address narrow_oop_base() { return _narrow_oop._base; } + static address narrow_oop_base() { return _narrow_oop._base; } + // Test whether bits of addr and possible offsets into the heap overlap. + static bool is_disjoint_heap_base_address(address addr) { + return (((uint64_t)(intptr_t)addr) & + (((uint64_t)UCONST64(0xFFFFffffFFFFffff)) >> (32-LogMinObjAlignmentInBytes))) == 0; + } + // Check for disjoint base compressed oops. + static bool narrow_oop_base_disjoint() { + return _narrow_oop._base != NULL && is_disjoint_heap_base_address(_narrow_oop._base); + } + // Check for real heapbased compressed oops. + // We must subtract the base as the bits overlap. + // If we negate above function, we also get unscaled and zerobased. + static bool narrow_oop_base_overlaps() { + return _narrow_oop._base != NULL && !is_disjoint_heap_base_address(_narrow_oop._base); + } static bool is_narrow_oop_base(void* addr) { return (narrow_oop_base() == (address)addr); } static int narrow_oop_shift() { return _narrow_oop._shift; } static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; } @@ -461,16 +484,6 @@ static uintptr_t verify_mark_bits() PRODUCT_RETURN0; static uintptr_t verify_mark_mask() PRODUCT_RETURN0; - // Flushing and deoptimization - static void flush_dependents_on(instanceKlassHandle dependee); - static void flush_dependents_on(Handle call_site, Handle method_handle); -#ifdef HOTSWAP - // Flushing and deoptimization in case of evolution - static void flush_evol_dependents_on(instanceKlassHandle dependee); -#endif // HOTSWAP - // Support for fullspeed debugging - static void flush_dependents_on_method(methodHandle dependee); - // Compiler support static int base_vtable_size() { return _base_vtable_size; } }; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/fieldStreams.hpp --- a/hotspot/src/share/vm/oops/fieldStreams.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -51,7 +51,7 @@ int init_generic_signature_start_slot() { int length = _fields->length(); - int num_fields = 0; + int num_fields = _index; int skipped_generic_signature_slots = 0; FieldInfo* fi; AccessFlags flags; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -3543,11 +3543,12 @@ ("purge: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(), method->signature()->as_C_string(), j, version)); +#ifdef ASSERT if (method->method_data() != NULL) { - // Clean out any weak method links for running methods - // (also should include not EMCP methods) - method->method_data()->clean_weak_method_links(); + // Verify MethodData for running methods don't refer to old methods. + method->method_data()->verify_clean_weak_method_links(); } +#endif // ASSERT } } } @@ -3561,15 +3562,17 @@ deleted_count)); } - // Clean MethodData of this class's methods so they don't refer to +#ifdef ASSERT + // Verify clean MethodData for this class's methods, e.g. they don't refer to // old methods that are no longer running. Array* methods = ik->methods(); int num_methods = methods->length(); - for (int index2 = 0; index2 < num_methods; ++index2) { - if (methods->at(index2)->method_data() != NULL) { - methods->at(index2)->method_data()->clean_weak_method_links(); + for (int index = 0; index < num_methods; ++index) { + if (methods->at(index)->method_data() != NULL) { + methods->at(index)->method_data()->verify_clean_weak_method_links(); } } +#endif // ASSERT } void InstanceKlass::mark_newly_obsolete_methods(Array* old_methods, diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/klassVtable.cpp --- a/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/klassVtable.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,17 +100,21 @@ vtable_length = Universe::base_vtable_size(); } - if (super == NULL && !Universe::is_bootstrapping() && - vtable_length != Universe::base_vtable_size()) { - // Someone is attempting to redefine java.lang.Object incorrectly. The - // only way this should happen is from - // SystemDictionary::resolve_from_stream(), which will detect this later - // and throw a security exception. So don't assert here to let - // the exception occur. - vtable_length = Universe::base_vtable_size(); + if (super == NULL && vtable_length != Universe::base_vtable_size()) { + if (Universe::is_bootstrapping()) { + // Someone is attempting to override java.lang.Object incorrectly on the + // bootclasspath. The JVM cannot recover from this error including throwing + // an exception + vm_exit_during_initialization("Incompatible definition of java.lang.Object"); + } else { + // Someone is attempting to redefine java.lang.Object incorrectly. The + // only way this should happen is from + // SystemDictionary::resolve_from_stream(), which will detect this later + // and throw a security exception. So don't assert here to let + // the exception occur. + vtable_length = Universe::base_vtable_size(); + } } - assert(super != NULL || vtable_length == Universe::base_vtable_size(), - "bad vtable size for class Object"); assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/method.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/metadataOnStackMark.hpp" #include "classfile/systemDictionary.hpp" +#include "code/codeCache.hpp" #include "code/debugInfoRec.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "interpreter/bytecodeStream.hpp" @@ -1727,7 +1728,7 @@ // Deoptimize all dependents on this method HandleMark hm(thread); methodHandle mh(thread, method); - Universe::flush_dependents_on_method(mh); + CodeCache::flush_dependents_on_method(mh); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/methodData.cpp --- a/hotspot/src/share/vm/oops/methodData.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/methodData.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1283,6 +1283,11 @@ DataLayout::compute_size_in_bytes(SpeculativeTrapData::static_cell_count()), "code needs to be adjusted"); + // Do not create one of these if method has been redefined. + if (m != NULL && m->is_old()) { + return NULL; + } + DataLayout* dp = extra_data_base(); DataLayout* end = args_data_limit(); @@ -1554,9 +1559,7 @@ class CleanExtraDataMethodClosure : public CleanExtraDataClosure { public: CleanExtraDataMethodClosure() {} - bool is_live(Method* m) { - return !m->is_old() || m->on_stack(); - } + bool is_live(Method* m) { return !m->is_old(); } }; @@ -1658,3 +1661,16 @@ clean_extra_data(&cl); verify_extra_data_clean(&cl); } + +#ifdef ASSERT +void MethodData::verify_clean_weak_method_links() { + for (ProfileData* data = first_data(); + is_valid(data); + data = next_data(data)) { + data->verify_clean_weak_method_links(); + } + + CleanExtraDataMethodClosure cl; + verify_extra_data_clean(&cl); +} +#endif // ASSERT diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/oops/methodData.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -254,6 +254,7 @@ // Redefinition support void clean_weak_method_links(); + DEBUG_ONLY(void verify_clean_weak_method_links();) }; @@ -511,6 +512,7 @@ // Redefinition support virtual void clean_weak_method_links() {} + DEBUG_ONLY(virtual void verify_clean_weak_method_links() {}) // CI translation: ProfileData can represent both MethodDataOop data // as well as CIMethodData data. This function is provided for translating @@ -1971,6 +1973,7 @@ } void set_method(Method* m) { + assert(!m->is_old(), "cannot add old methods"); set_intptr_at(speculative_trap_method, (intptr_t)m); } @@ -2480,6 +2483,7 @@ void clean_method_data(BoolObjectClosure* is_alive); void clean_weak_method_links(); + DEBUG_ONLY(void verify_clean_weak_method_links();) Mutex* extra_data_lock() { return &_extra_data_lock; } }; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -669,6 +669,13 @@ product_pd(bool, TrapBasedRangeChecks, \ "Generate code for range checks that uses a cmp and trap " \ "instruction raising SIGTRAP. Used on PPC64.") \ + \ + product(intx, ArrayCopyLoadStoreMaxElem, 8, \ + "Maximum number of arraycopy elements inlined as a sequence of" \ + "loads/stores") \ + \ + develop(bool, StressArrayCopyMacroNode, false, \ + "Perform ArrayCopy load/store replacement during IGVN only") C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/c2compiler.cpp --- a/hotspot/src/share/vm/opto/c2compiler.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2compiler.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -39,6 +39,9 @@ const char* C2Compiler::retry_no_escape_analysis() { return "retry without escape analysis"; } +const char* C2Compiler::retry_class_loading_during_parsing() { + return "retry class loading during parsing"; +} bool C2Compiler::init_c2_runtime() { // Check assumptions used while running ADLC @@ -104,6 +107,10 @@ // Check result and retry if appropriate. if (C.failure_reason() != NULL) { + if (C.failure_reason_is(retry_class_loading_during_parsing())) { + env->report_failure(C.failure_reason()); + continue; // retry + } if (C.failure_reason_is(retry_no_subsuming_loads())) { assert(subsume_loads, "must make progress"); subsume_loads = false; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/c2compiler.hpp --- a/hotspot/src/share/vm/opto/c2compiler.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2compiler.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -47,6 +47,7 @@ // sentinel value used to trigger backtracking in compile_method(). static const char* retry_no_subsuming_loads(); static const char* retry_no_escape_analysis(); + static const char* retry_class_loading_during_parsing(); // Print compilation timers and statistics void print_timers(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/callnode.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -28,6 +28,7 @@ #include "opto/callGenerator.hpp" #include "opto/callnode.hpp" #include "opto/castnode.hpp" +#include "opto/convertnode.hpp" #include "opto/escape.hpp" #include "opto/locknode.hpp" #include "opto/machnode.hpp" @@ -1818,7 +1819,10 @@ } ArrayCopyNode::ArrayCopyNode(Compile* C, bool alloc_tightly_coupled) - : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM), _alloc_tightly_coupled(alloc_tightly_coupled), _kind(ArrayCopy) { + : CallNode(arraycopy_type(), NULL, TypeRawPtr::BOTTOM), + _alloc_tightly_coupled(alloc_tightly_coupled), + _kind(None), + _arguments_validated(false) { init_class_id(Class_ArrayCopy); init_flags(Flag_is_macro); C->add_macro_node(this); @@ -1870,3 +1874,136 @@ st->print(" (%s%s)", _kind_names[_kind], _alloc_tightly_coupled ? ", tightly coupled allocation" : ""); } #endif + +int ArrayCopyNode::get_count(PhaseGVN *phase) const { + Node* src = in(ArrayCopyNode::Src); + const Type* src_type = phase->type(src); + + assert(is_clonebasic(), "unexpected arraycopy type"); + if (src_type->isa_instptr()) { + const TypeInstPtr* inst_src = src_type->is_instptr(); + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + // ciInstanceKlass::nof_nonstatic_fields() doesn't take injected + // fields into account. They are rare anyway so easier to simply + // skip instances with injected fields. + if ((!inst_src->klass_is_exact() && (ik->is_interface() || ik->has_subklass())) || ik->has_injected_fields()) { + return -1; + } + int nb_fields = ik->nof_nonstatic_fields(); + return nb_fields; + } + return -1; +} + +Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int count) { + assert(is_clonebasic(), "unexpected arraycopy type"); + + Node* src = in(ArrayCopyNode::Src); + Node* dest = in(ArrayCopyNode::Dest); + Node* ctl = in(TypeFunc::Control); + Node* in_mem = in(TypeFunc::Memory); + + const Type* src_type = phase->type(src); + const Type* dest_type = phase->type(dest); + + assert(src->is_AddP(), "should be base + off"); + assert(dest->is_AddP(), "should be base + off"); + Node* base_src = src->in(AddPNode::Base); + Node* base_dest = dest->in(AddPNode::Base); + + MergeMemNode* mem = MergeMemNode::make(in_mem); + + const TypeInstPtr* inst_src = src_type->is_instptr(); + + if (!inst_src->klass_is_exact()) { + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy"); + phase->C->dependencies()->assert_leaf_type(ik); + } + + ciInstanceKlass* ik = inst_src->klass()->as_instance_klass(); + assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields"); + + for (int i = 0; i < count; i++) { + ciField* field = ik->nonstatic_field_at(i); + int fieldidx = phase->C->alias_type(field)->index(); + const TypePtr* adr_type = phase->C->alias_type(field)->adr_type(); + Node* off = phase->MakeConX(field->offset()); + Node* next_src = phase->transform(new AddPNode(base_src,base_src,off)); + Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off)); + BasicType bt = field->layout_type(); + + const Type *type; + if (bt == T_OBJECT) { + if (!field->type()->is_loaded()) { + type = TypeInstPtr::BOTTOM; + } else { + ciType* field_klass = field->type(); + type = TypeOopPtr::make_from_klass(field_klass->as_klass()); + } + } else { + type = Type::get_const_basic_type(bt); + } + + Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered); + v = phase->transform(v); + Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered); + s = phase->transform(s); + mem->set_memory_at(fieldidx, s); + } + + if (!finish_transform(phase, can_reshape, ctl, mem)) { + return NULL; + } + + return mem; +} + +bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape, + Node* ctl, Node *mem) { + if (can_reshape) { + PhaseIterGVN* igvn = phase->is_IterGVN(); + assert(is_clonebasic(), "unexpected arraycopy type"); + Node* out_mem = proj_out(TypeFunc::Memory); + + if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() || + out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) { + assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking"); + return false; + } + + igvn->replace_node(out_mem->raw_out(0), mem); + + Node* out_ctl = proj_out(TypeFunc::Control); + igvn->replace_node(out_ctl, ctl); + } + return true; +} + + +Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) { + + if (StressArrayCopyMacroNode && !can_reshape) return NULL; + + // See if it's a small array copy and we can inline it as + // loads/stores + // Here we can only do: + // - clone for which we don't need to do card marking + + if (!is_clonebasic()) { + return NULL; + } + + if (in(TypeFunc::Control)->is_top() || in(TypeFunc::Memory)->is_top()) { + return NULL; + } + + int count = get_count(phase); + + if (count < 0 || count > ArrayCopyLoadStoreMaxElem) { + return NULL; + } + + Node* mem = try_clone_instance(phase, can_reshape, count); + return mem; +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/callnode.hpp --- a/hotspot/src/share/vm/opto/callnode.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/callnode.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1070,8 +1070,8 @@ // What kind of arraycopy variant is this? enum { + None, // not set yet ArrayCopy, // System.arraycopy() - ArrayCopyNoTest, // System.arraycopy(), all arguments validated CloneBasic, // A clone that can be copied by 64 bit chunks CloneOop, // An oop array clone CopyOf, // Arrays.copyOf() @@ -1095,6 +1095,8 @@ // LibraryCallKit::tightly_coupled_allocation() is called. bool _alloc_tightly_coupled; + bool _arguments_validated; + static const TypeFunc* arraycopy_type() { const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms); fields[Src] = TypeInstPtr::BOTTOM; @@ -1118,6 +1120,13 @@ ArrayCopyNode(Compile* C, bool alloc_tightly_coupled); + int get_count(PhaseGVN *phase) const; + static const TypePtr* get_address_type(PhaseGVN *phase, Node* n); + + Node* try_clone_instance(PhaseGVN *phase, bool can_reshape, int count); + bool finish_transform(PhaseGVN *phase, bool can_reshape, + Node* ctl, Node *mem); + public: enum { @@ -1143,23 +1152,23 @@ void connect_outputs(GraphKit* kit); - bool is_arraycopy() const { return _kind == ArrayCopy; } - bool is_arraycopy_notest() const { return _kind == ArrayCopyNoTest; } - bool is_clonebasic() const { return _kind == CloneBasic; } - bool is_cloneoop() const { return _kind == CloneOop; } - bool is_copyof() const { return _kind == CopyOf; } - bool is_copyofrange() const { return _kind == CopyOfRange; } + bool is_arraycopy() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy; } + bool is_arraycopy_validated() const { assert(_kind != None, "should bet set"); return _kind == ArrayCopy && _arguments_validated; } + bool is_clonebasic() const { assert(_kind != None, "should bet set"); return _kind == CloneBasic; } + bool is_cloneoop() const { assert(_kind != None, "should bet set"); return _kind == CloneOop; } + bool is_copyof() const { assert(_kind != None, "should bet set"); return _kind == CopyOf; } + bool is_copyofrange() const { assert(_kind != None, "should bet set"); return _kind == CopyOfRange; } - void set_arraycopy() { _kind = ArrayCopy; } - void set_arraycopy_notest() { _kind = ArrayCopyNoTest; } - void set_clonebasic() { _kind = CloneBasic; } - void set_cloneoop() { _kind = CloneOop; } - void set_copyof() { _kind = CopyOf; } - void set_copyofrange() { _kind = CopyOfRange; } + void set_arraycopy(bool validated) { assert(_kind == None, "shouldn't bet set yet"); _kind = ArrayCopy; _arguments_validated = validated; } + void set_clonebasic() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneBasic; } + void set_cloneoop() { assert(_kind == None, "shouldn't bet set yet"); _kind = CloneOop; } + void set_copyof() { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOf; _arguments_validated = false; } + void set_copyofrange() { assert(_kind == None, "shouldn't bet set yet"); _kind = CopyOfRange; _arguments_validated = false; } virtual int Opcode() const; virtual uint size_of() const; // Size is bigger virtual bool guaranteed_safepoint() { return false; } + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); bool is_alloc_tightly_coupled() const { return _alloc_tightly_coupled; } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/compile.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -774,7 +774,9 @@ } JVMState* jvms = build_start_state(start(), tf()); if ((jvms = cg->generate(jvms)) == NULL) { - record_method_not_compilable("method parse failed"); + if (!failure_reason_is(C2Compiler::retry_class_loading_during_parsing())) { + record_method_not_compilable("method parse failed"); + } return; } GraphKit kit(jvms); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/library_call.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -4475,8 +4475,11 @@ ArrayCopyNode* ac = ArrayCopyNode::make(this, false, src, NULL, dest, NULL, countx, false); ac->set_clonebasic(); Node* n = _gvn.transform(ac); - assert(n == ac, "cannot disappear"); - set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); + if (n == ac) { + set_predefined_output_for_runtime_call(ac, ac->in(TypeFunc::Memory), raw_adr_type); + } else { + set_all_memory(n); + } // If necessary, emit some card marks afterwards. (Non-arrays only.) if (card_mark) { @@ -4541,6 +4544,26 @@ Node* obj = null_check_receiver(); if (stopped()) return true; + const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); + + // If we are going to clone an instance, we need its exact type to + // know the number and types of fields to convert the clone to + // loads/stores. Maybe a speculative type can help us. + if (!obj_type->klass_is_exact() && + obj_type->speculative_type() != NULL && + obj_type->speculative_type()->is_instance_klass()) { + ciInstanceKlass* spec_ik = obj_type->speculative_type()->as_instance_klass(); + if (spec_ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem && + !spec_ik->has_injected_fields()) { + ciKlass* k = obj_type->klass(); + if (!k->is_instance_klass() || + k->as_instance_klass()->is_interface() || + k->as_instance_klass()->has_subklass()) { + obj = maybe_cast_profiled_obj(obj, obj_type->speculative_type(), false); + } + } + } + Node* obj_klass = load_object_klass(obj); const TypeKlassPtr* tklass = _gvn.type(obj_klass)->isa_klassptr(); const TypeOopPtr* toop = ((tklass != NULL) @@ -4743,7 +4766,7 @@ sfpt->set_memory(map()->memory()); } - bool notest = false; + bool validated = false; const Type* src_type = _gvn.type(src); const Type* dest_type = _gvn.type(dest); @@ -4847,7 +4870,7 @@ if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { // validate arguments: enables transformation the ArrayCopyNode - notest = true; + validated = true; RegionNode* slow_region = new RegionNode(1); record_for_igvn(slow_region); @@ -4922,13 +4945,15 @@ load_object_klass(src), load_object_klass(dest), load_array_length(src), load_array_length(dest)); - if (notest) { - ac->set_arraycopy_notest(); - } + ac->set_arraycopy(validated); Node* n = _gvn.transform(ac); - assert(n == ac, "cannot disappear"); - ac->connect_outputs(this); + if (n == ac) { + ac->connect_outputs(this); + } else { + assert(validated, "shouldn't transform if all arguments not validated"); + set_all_memory(n); + } return true; } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/macroArrayCopy.cpp --- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -519,7 +519,8 @@ // Test S[] against D[], not S against D, because (probably) // the secondary supertype cache is less busy for S[] than S. // This usually only matters when D is an interface. - Node* not_subtype_ctrl = ac->is_arraycopy_notest() ? top() : Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn); + Node* not_subtype_ctrl = ac->is_arraycopy_validated() ? top() : + Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn); // Plug failing path into checked_oop_disjoint_arraycopy if (not_subtype_ctrl != top()) { Node* local_ctrl = not_subtype_ctrl; @@ -1109,7 +1110,7 @@ assert(alloc != NULL, "expect alloc"); } - assert(ac->is_arraycopy() || ac->is_arraycopy_notest(), "should be an arraycopy"); + assert(ac->is_arraycopy() || ac->is_arraycopy_validated(), "should be an arraycopy"); // Compile time checks. If any of these checks cannot be verified at compile time, // we do not make a fast path for this call. Instead, we let the call remain as it @@ -1191,7 +1192,7 @@ RegionNode* slow_region = new RegionNode(1); transform_later(slow_region); - if (!ac->is_arraycopy_notest()) { + if (!ac->is_arraycopy_validated()) { // (3) operands must not be null // We currently perform our null checks with the null_check routine. // This means that the null exceptions will be reported in the caller diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/matcher.hpp --- a/hotspot/src/share/vm/opto/matcher.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/matcher.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -433,6 +433,13 @@ // NullCheck oop_reg // inline static bool gen_narrow_oop_implicit_null_checks() { + // Advice matcher to perform null checks on the narrow oop side. + // Implicit checks are not possible on the uncompressed oop side anyway + // (at least not for read accesses). + // Performs significantly better (especially on Power 6). + if (!os::zero_page_read_protected()) { + return true; + } return Universe::narrow_oop_use_implicit_null_checks() && (narrow_oop_use_complex_address() || Universe::narrow_oop_base() != NULL); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/opto/parse1.cpp --- a/hotspot/src/share/vm/opto/parse1.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/opto/parse1.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -27,6 +27,7 @@ #include "interpreter/linkResolver.hpp" #include "oops/method.hpp" #include "opto/addnode.hpp" +#include "opto/c2compiler.hpp" #include "opto/castnode.hpp" #include "opto/idealGraphPrinter.hpp" #include "opto/locknode.hpp" @@ -986,7 +987,18 @@ if (tf()->range()->cnt() > TypeFunc::Parms) { const Type* ret_type = tf()->range()->field_at(TypeFunc::Parms); Node* ret_phi = _gvn.transform( _exits.argument(0) ); - assert(_exits.control()->is_top() || !_gvn.type(ret_phi)->empty(), "return value must be well defined"); + if (!_exits.control()->is_top() && _gvn.type(ret_phi)->empty()) { + // In case of concurrent class loading, the type we set for the + // ret_phi in build_exits() may have been too optimistic and the + // ret_phi may be top now. +#ifdef ASSERT + { + MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag); + assert(ret_type->isa_ptr() && C->env()->system_dictionary_modification_counter_changed(), "return value must be well defined"); + } +#endif + C->record_failure(C2Compiler::retry_class_loading_during_parsing()); + } _exits.push_node(ret_type->basic_type(), ret_phi); } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,6 +148,10 @@ _scratch_classes[i] = NULL; } + // Clean out MethodData pointing to old Method* + MethodDataCleaner clean_weak_method_links; + ClassLoaderDataGraph::classes_do(&clean_weak_method_links); + // Disable any dependent concurrent compilations SystemDictionary::notice_modification(); @@ -155,8 +159,8 @@ // See jvmtiExport.hpp for detailed explanation. JvmtiExport::set_has_redefined_a_class(); -// check_class() is optionally called for product bits, but is -// always called for non-product bits. + // check_class() is optionally called for product bits, but is + // always called for non-product bits. #ifdef PRODUCT if (RC_TRACE_ENABLED(0x00004000)) { #endif @@ -3445,6 +3449,22 @@ } } +// Clean method data for this class +void VM_RedefineClasses::MethodDataCleaner::do_klass(Klass* k) { + if (k->oop_is_instance()) { + InstanceKlass *ik = InstanceKlass::cast(k); + // Clean MethodData of this class's methods so they don't refer to + // old methods that are no longer running. + Array* methods = ik->methods(); + int num_methods = methods->length(); + for (int index = 0; index < num_methods; ++index) { + if (methods->at(index)->method_data() != NULL) { + methods->at(index)->method_data()->clean_weak_method_links(); + } + } + } +} + void VM_RedefineClasses::update_jmethod_ids() { for (int j = 0; j < _matching_methods_length; ++j) { Method* old_method = _matching_old_methods[j]; @@ -3746,7 +3766,7 @@ // All dependencies have been recorded from startup or this is a second or // subsequent use of RedefineClasses if (JvmtiExport::all_dependencies_are_recorded()) { - Universe::flush_evol_dependents_on(k_h); + CodeCache::flush_evol_dependents_on(k_h); } else { CodeCache::mark_all_nmethods_for_deoptimization(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -511,6 +511,12 @@ void do_klass(Klass* k); }; + // Clean MethodData out + class MethodDataCleaner : public KlassClosure { + public: + MethodDataCleaner() {} + void do_klass(Klass* k); + }; public: VM_RedefineClasses(jint class_count, const jvmtiClassDefinition *class_defs, diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/stringTable.hpp" +#include "code/codeCache.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/oopMapCache.hpp" @@ -1245,7 +1246,7 @@ { // Walk all nmethods depending on this call site. MutexLocker mu(Compile_lock, thread); - Universe::flush_dependents_on(call_site, target); + CodeCache::flush_dependents_on(call_site, target); java_lang_invoke_CallSite::set_target(call_site(), target()); } } @@ -1257,7 +1258,7 @@ { // Walk all nmethods depending on this call site. MutexLocker mu(Compile_lock, thread); - Universe::flush_dependents_on(call_site, target); + CodeCache::flush_dependents_on(call_site, target); java_lang_invoke_CallSite::set_target_volatile(call_site(), target()); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,11 +176,11 @@ WB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o)) size_t granularity = os::vm_allocation_granularity(); - ReservedHeapSpace rhs(100 * granularity, granularity, false, NULL); + ReservedHeapSpace rhs(100 * granularity, granularity, false); VirtualSpace vs; vs.initialize(rhs, 50 * granularity); - //Check if constraints are complied + // Check if constraints are complied if (!( UseCompressedOops && rhs.base() != NULL && Universe::narrow_oop_base() != NULL && Universe::narrow_oop_use_implicit_null_checks() )) { @@ -203,7 +203,7 @@ static jint wb_stress_virtual_space_resize(size_t reserved_space_size, size_t magnitude, size_t iterations) { size_t granularity = os::vm_allocation_granularity(); - ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false, NULL); + ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false); VirtualSpace vs; if (!vs.initialize(rhs, 0)) { tty->print_cr("Failed to initialize VirtualSpace. Can't proceed."); @@ -1123,6 +1123,16 @@ attemptedNoSafepointValue == JNI_TRUE); WB_END +WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj)) + oop obj_oop = JNIHandles::resolve(obj); + return (jboolean) obj_oop->mark()->has_monitor(); +WB_END + +WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb)) + VM_ForceSafepoint force_safepoint_op; + VMThread::execute(&force_safepoint_op); +WB_END + //Some convenience methods to deal with objects from java int WhiteBox::offset_for_field(const char* field_name, oop object, Symbol* signature_symbol) { @@ -1321,6 +1331,8 @@ {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, {CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls }, + {CC"isMonitorInflated", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated }, + {CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint }, }; #undef CC diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1522,15 +1522,6 @@ FLAG_SET_ERGO(bool, UseCompressedOops, true); } #endif -#ifdef _WIN64 - if (UseLargePages && UseCompressedOops) { - // Cannot allocate guard pages for implicit checks in indexed addressing - // mode, when large pages are specified on windows. - // This flag could be switched ON if narrow oop base address is set to 0, - // see code in Universe::initialize_heap(). - Universe::set_narrow_oop_use_implicit_null_checks(false); - } -#endif // _WIN64 } else { if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { warning("Max heap size too large for Compressed Oops"); @@ -2416,6 +2407,7 @@ #ifdef COMPILER1 status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize"); #endif + status = status && verify_min_value(HeapSearchSteps, 1, "HeapSearchSteps"); if (PrintNMTStatistics) { #if INCLUDE_NMT @@ -4102,6 +4094,10 @@ PropertyList_add(plist, new_p); } +void Arguments::PropertyList_add(SystemProperty *element) { + PropertyList_add(&_system_properties, element); +} + // This add maintains unique property key in the list. void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, char* v, jboolean append) { if (plist == NULL) diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -572,6 +572,7 @@ static void init_version_specific_system_properties(); // Property List manipulation + static void PropertyList_add(SystemProperty *element); static void PropertyList_add(SystemProperty** plist, SystemProperty *element); static void PropertyList_add(SystemProperty** plist, const char* k, char* v); static void PropertyList_unique_add(SystemProperty** plist, const char* k, char* v) { diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -531,6 +531,11 @@ product_pd(uintx, HeapBaseMinAddress, \ "OS specific low limit for heap base address") \ \ + product(uintx, HeapSearchSteps, 3 PPC64_ONLY(+17), \ + "Heap allocation steps through preferred address regions to find" \ + " where it can allocate the heap. Number of steps to take per " \ + "region.") \ + \ diagnostic(bool, PrintCompressedOopsMode, false, \ "Print compressed oops base address and encoding mode") \ \ @@ -3779,6 +3784,9 @@ NOT_LP64(LINUX_ONLY(2*G) NOT_LINUX(0)), \ "Address to allocate shared memory region for class data") \ \ + product(uintx, SharedSymbolTableBucketSize, 4, \ + "Average number of symbols per bucket in shared table") \ + \ diagnostic(bool, IgnoreUnverifiableClassesDuringDump, false, \ "Do not quit -Xshare:dump even if we encounter unverifiable " \ "classes. Just exclude them from the shared dictionary.") \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/virtualspace.cpp --- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,21 +43,19 @@ // Don't force the alignment to be large page aligned, // since that will waste memory. size_t alignment = os::vm_allocation_granularity(); - initialize(size, alignment, large_pages, NULL, 0, false); + initialize(size, alignment, large_pages, NULL, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address, - const size_t noaccess_prefix) { - initialize(size+noaccess_prefix, alignment, large, requested_address, - noaccess_prefix, false); + char* requested_address) { + initialize(size, alignment, large, requested_address, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, bool executable) { - initialize(size, alignment, large, NULL, 0, executable); + initialize(size, alignment, large, NULL, executable); } // Helper method. @@ -91,7 +89,6 @@ void ReservedSpace::initialize(size_t size, size_t alignment, bool large, char* requested_address, - const size_t noaccess_prefix, bool executable) { const size_t granularity = os::vm_allocation_granularity(); assert((size & (granularity - 1)) == 0, @@ -103,10 +100,6 @@ alignment = MAX2(alignment, (size_t)os::vm_page_size()); - // Assert that if noaccess_prefix is used, it is the same as alignment. - assert(noaccess_prefix == 0 || - noaccess_prefix == alignment, "noaccess prefix wrong"); - _base = NULL; _size = 0; _special = false; @@ -122,11 +115,6 @@ bool special = large && !os::can_commit_large_page_memory(); char* base = NULL; - if (requested_address != 0) { - requested_address -= noaccess_prefix; // adjust requested address - assert(requested_address != NULL, "huge noaccess prefix?"); - } - if (special) { base = os::reserve_memory_special(size, alignment, requested_address, executable); @@ -176,7 +164,7 @@ if (base == NULL) return; // Check alignment constraints - if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) { + if ((((size_t)base) & (alignment - 1)) != 0) { // Base not aligned, retry if (!os::release_memory(base, size)) fatal("os::release_memory failed"); // Make sure that size is aligned @@ -197,16 +185,6 @@ _base = base; _size = size; _alignment = alignment; - _noaccess_prefix = noaccess_prefix; - - // Assert that if noaccess_prefix is used, it is the same as alignment. - assert(noaccess_prefix == 0 || - noaccess_prefix == _alignment, "noaccess prefix wrong"); - - assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, - "area must be distinguishable from marks for mark-sweep"); - assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], - "area must be distinguishable from marks for mark-sweep"); } @@ -276,54 +254,336 @@ _base = NULL; _size = 0; _noaccess_prefix = 0; + _alignment = 0; _special = false; _executable = false; } } -void ReservedSpace::protect_noaccess_prefix(const size_t size) { - assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL && - (Universe::narrow_oop_base() != NULL) && - Universe::narrow_oop_use_implicit_null_checks()), - "noaccess_prefix should be used only with non zero based compressed oops"); +static size_t noaccess_prefix_size(size_t alignment) { + return lcm(os::vm_page_size(), alignment); +} - // If there is no noaccess prefix, return. - if (_noaccess_prefix == 0) return; +void ReservedHeapSpace::establish_noaccess_prefix() { + assert(_alignment >= (size_t)os::vm_page_size(), "must be at least page size big"); + _noaccess_prefix = noaccess_prefix_size(_alignment); - assert(_noaccess_prefix >= (size_t)os::vm_page_size(), - "must be at least page size big"); - - // Protect memory at the base of the allocated region. - // If special, the page was committed (only matters on windows) - if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, - _special)) { - fatal("cannot protect protection page"); - } - if (PrintCompressedOopsMode) { - tty->cr(); - tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); + if (base() && base() + _size > (char *)OopEncodingHeapMax) { + if (true + WIN64_ONLY(&& !UseLargePages) + AIX_ONLY(&& os::vm_page_size() != SIZE_64K)) { + // Protect memory at the base of the allocated region. + // If special, the page was committed (only matters on windows) + if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) { + fatal("cannot protect protection page"); + } + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Protected page at the reserved heap base: " + PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); + } + assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?"); + } else { + Universe::set_narrow_oop_use_implicit_null_checks(false); + } } _base += _noaccess_prefix; _size -= _noaccess_prefix; - assert((size == _size) && ((uintptr_t)_base % _alignment == 0), - "must be exactly of required size and alignment"); + assert(((uintptr_t)_base % _alignment == 0), "must be exactly of required alignment"); +} + +// Tries to allocate memory of size 'size' at address requested_address with alignment 'alignment'. +// Does not check whether the reserved memory actually is at requested_address, as the memory returned +// might still fulfill the wishes of the caller. +// Assures the memory is aligned to 'alignment'. +// NOTE: If ReservedHeapSpace already points to some reserved memory this is freed, first. +void ReservedHeapSpace::try_reserve_heap(size_t size, + size_t alignment, + bool large, + char* requested_address) { + if (_base != NULL) { + // We tried before, but we didn't like the address delivered. + release(); + } + + // If OS doesn't support demand paging for large page memory, we need + // to use reserve_memory_special() to reserve and pin the entire region. + bool special = large && !os::can_commit_large_page_memory(); + char* base = NULL; + + if (PrintCompressedOopsMode && Verbose) { + tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " PTR_FORMAT ".\n", + requested_address, (address)size); + } + + if (special) { + base = os::reserve_memory_special(size, alignment, requested_address, false); + + if (base != NULL) { + // Check alignment constraints. + assert((uintptr_t) base % alignment == 0, + err_msg("Large pages returned a non-aligned address, base: " + PTR_FORMAT " alignment: " PTR_FORMAT, + base, (void*)(uintptr_t)alignment)); + _special = true; + } + } + + if (base == NULL) { + // Failed; try to reserve regular memory below + if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || + !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserve regular memory without large pages."); + } + } + + // Optimistically assume that the OSes returns an aligned base pointer. + // When reserving a large address range, most OSes seem to align to at + // least 64K. + + // If the memory was requested at a particular address, use + // os::attempt_reserve_memory_at() to avoid over mapping something + // important. If available space is not detected, return NULL. + + if (requested_address != 0) { + base = os::attempt_reserve_memory_at(size, requested_address); + } else { + base = os::reserve_memory(size, NULL, alignment); + } + } + if (base == NULL) { return; } + + // Done + _base = base; + _size = size; + _alignment = alignment; + + // Check alignment constraints + if ((((size_t)base) & (alignment - 1)) != 0) { + // Base not aligned, retry. + release(); + } +} + +void ReservedHeapSpace::try_reserve_range(char *highest_start, + char *lowest_start, + size_t attach_point_alignment, + char *aligned_heap_base_min_address, + char *upper_bound, + size_t size, + size_t alignment, + bool large) { + const size_t attach_range = highest_start - lowest_start; + // Cap num_attempts at possible number. + // At least one is possible even for 0 sized attach range. + const uint64_t num_attempts_possible = (attach_range / attach_point_alignment) + 1; + const uint64_t num_attempts_to_try = MIN2((uint64_t)HeapSearchSteps, num_attempts_possible); + + const size_t stepsize = (attach_range == 0) ? // Only one try. + (size_t) highest_start : align_size_up(attach_range / num_attempts_to_try, attach_point_alignment); + + // Try attach points from top to bottom. + char* attach_point = highest_start; + while (attach_point >= lowest_start && + attach_point <= highest_start && // Avoid wrap around. + ((_base == NULL) || + (_base < aligned_heap_base_min_address || _base + size > upper_bound))) { + try_reserve_heap(size, alignment, large, attach_point); + attach_point -= stepsize; + } } -ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, - bool large, char* requested_address) : - ReservedSpace(size, alignment, large, - requested_address, - (UseCompressedOops && (Universe::narrow_oop_base() != NULL) && - Universe::narrow_oop_use_implicit_null_checks()) ? - lcm(os::vm_page_size(), alignment) : 0) { +#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) +#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) +#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) + +// Helper for heap allocation. Returns an array with addresses +// (OS-specific) which are suited for disjoint base mode. Array is +// NULL terminated. +static char** get_attach_addresses_for_disjoint_mode() { + static uint64_t addresses[] = { + 2 * SIZE_32G, + 3 * SIZE_32G, + 4 * SIZE_32G, + 8 * SIZE_32G, + 10 * SIZE_32G, + 1 * SIZE_64K * SIZE_32G, + 2 * SIZE_64K * SIZE_32G, + 3 * SIZE_64K * SIZE_32G, + 4 * SIZE_64K * SIZE_32G, + 16 * SIZE_64K * SIZE_32G, + 32 * SIZE_64K * SIZE_32G, + 34 * SIZE_64K * SIZE_32G, + 0 + }; + + // Sort out addresses smaller than HeapBaseMinAddress. This assumes + // the array is sorted. + uint i = 0; + while (addresses[i] != 0 && + (addresses[i] < OopEncodingHeapMax || addresses[i] < HeapBaseMinAddress)) { + i++; + } + uint start = i; + + // Avoid more steps than requested. + i = 0; + while (addresses[start+i] != 0) { + if (i == HeapSearchSteps) { + addresses[start+i] = 0; + break; + } + i++; + } + + return (char**) &addresses[start]; +} + +void ReservedHeapSpace::initialize_compressed_heap(const size_t size, size_t alignment, bool large) { + guarantee(size + noaccess_prefix_size(alignment) <= OopEncodingHeapMax, + "can not allocate compressed oop heap for this size"); + guarantee(alignment == MAX2(alignment, (size_t)os::vm_page_size()), "alignment too small"); + assert(HeapBaseMinAddress > 0, "sanity"); + + const size_t granularity = os::vm_allocation_granularity(); + assert((size & (granularity - 1)) == 0, + "size not aligned to os::vm_allocation_granularity()"); + assert((alignment & (granularity - 1)) == 0, + "alignment not aligned to os::vm_allocation_granularity()"); + assert(alignment == 0 || is_power_of_2((intptr_t)alignment), + "not a power of 2"); + + // The necessary attach point alignment for generated wish addresses. + // This is needed to increase the chance of attaching for mmap and shmat. + const size_t os_attach_point_alignment = + AIX_ONLY(SIZE_256M) // Known shm boundary alignment. + NOT_AIX(os::vm_allocation_granularity()); + const size_t attach_point_alignment = lcm(alignment, os_attach_point_alignment); + + char *aligned_heap_base_min_address = (char *)align_ptr_up((void *)HeapBaseMinAddress, alignment); + size_t noaccess_prefix = ((aligned_heap_base_min_address + size) > (char*)OopEncodingHeapMax) ? + noaccess_prefix_size(alignment) : 0; + + // Attempt to alloc at user-given address. + if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) { + try_reserve_heap(size + noaccess_prefix, alignment, large, aligned_heap_base_min_address); + if (_base != aligned_heap_base_min_address) { // Enforce this exact address. + release(); + } + } + + // Keep heap at HeapBaseMinAddress. + if (_base == NULL) { + + // Try to allocate the heap at addresses that allow efficient oop compression. + // Different schemes are tried, in order of decreasing optimization potential. + // + // For this, try_reserve_heap() is called with the desired heap base addresses. + // A call into the os layer to allocate at a given address can return memory + // at a different address than requested. Still, this might be memory at a useful + // address. try_reserve_heap() always returns this allocated memory, as only here + // the criteria for a good heap are checked. + + // Attempt to allocate so that we can run without base and scale (32-Bit unscaled compressed oops). + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= (char *)UnscaledOopHeapMax) { + + // Calc address range within we try to attach (range of possible start addresses). + char* const highest_start = (char *)align_ptr_down((char *)UnscaledOopHeapMax - size, attach_point_alignment); + char* const lowest_start = (char *)align_ptr_up ( aligned_heap_base_min_address , attach_point_alignment); + try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, (char *)UnscaledOopHeapMax, size, alignment, large); + } + + // zerobased: Attempt to allocate in the lower 32G. + // But leave room for the compressed class pointers, which is allocated above + // the heap. + char *zerobased_max = (char *)OopEncodingHeapMax; + // For small heaps, save some space for compressed class pointer + // space so it can be decoded with no base. + if (UseCompressedClassPointers && !UseSharedSpaces && + OopEncodingHeapMax <= KlassEncodingMetaspaceMax) { + const size_t class_space = align_size_up(CompressedClassSpaceSize, alignment); + zerobased_max = (char *)OopEncodingHeapMax - class_space; + } + + // Give it several tries from top of range to bottom. + if (aligned_heap_base_min_address + size <= zerobased_max && // Zerobased theoretical possible. + ((_base == NULL) || // No previous try succeeded. + (_base + size > zerobased_max))) { // Unscaled delivered an arbitrary address. + + // Calc address range within we try to attach (range of possible start addresses). + char *const highest_start = (char *)align_ptr_down(zerobased_max - size, attach_point_alignment); + // SS10 and SS12u1 cannot compile "(char *)UnscaledOopHeapMax - size" on solaris sparc 32-bit: + // "Cannot use int to initialize char*." Introduce aux variable. + char *unscaled_end = (char *)UnscaledOopHeapMax; + unscaled_end -= size; + char *lowest_start = (size < UnscaledOopHeapMax) ? + MAX2(unscaled_end, aligned_heap_base_min_address) : aligned_heap_base_min_address; + lowest_start = (char *)align_ptr_up(lowest_start, attach_point_alignment); + try_reserve_range(highest_start, lowest_start, attach_point_alignment, + aligned_heap_base_min_address, zerobased_max, size, alignment, large); + } + + // Now we go for heaps with base != 0. We need a noaccess prefix to efficiently + // implement null checks. + noaccess_prefix = noaccess_prefix_size(alignment); + + // Try to attach at addresses that are aligned to OopEncodingHeapMax. Disjointbase mode. + char** addresses = get_attach_addresses_for_disjoint_mode(); + int i = 0; + while (addresses[i] && // End of array not yet reached. + ((_base == NULL) || // No previous try succeeded. + (_base + size > (char *)OopEncodingHeapMax && // Not zerobased or unscaled address. + !Universe::is_disjoint_heap_base_address((address)_base)))) { // Not disjoint address. + char* const attach_point = addresses[i]; + assert(attach_point >= aligned_heap_base_min_address, "Flag support broken"); + try_reserve_heap(size + noaccess_prefix, alignment, large, attach_point); + i++; + } + + // Last, desperate try without any placement. + if (_base == NULL) { + if (PrintCompressedOopsMode && Verbose) { + tty->print("Trying to allocate at address NULL heap of size " PTR_FORMAT ".\n", (address)size + noaccess_prefix); + } + initialize(size + noaccess_prefix, alignment, large, NULL, false); + } + } +} + +ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large) : ReservedSpace() { + + if (size == 0) { + return; + } + + // Heap size should be aligned to alignment, too. + guarantee(is_size_aligned(size, alignment), "set by caller"); + + if (UseCompressedOops) { + initialize_compressed_heap(size, alignment, large); + if (_size > size) { + // We allocated heap with noaccess prefix. + // It can happen we get a zerobased/unscaled heap with noaccess prefix, + // if we had to try at arbitrary address. + establish_noaccess_prefix(); + } + } else { + initialize(size, alignment, large, NULL, false); + } + + assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, + "area must be distinguishable from marks for mark-sweep"); + assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], + "area must be distinguishable from marks for mark-sweep"); + if (base() > 0) { MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap); } - - // Only reserved space for the java heap should have a noaccess_prefix - // if using compressed oops. - protect_noaccess_prefix(size); } // Reserve space for code segment. Same as Java heap only we mark this as @@ -791,8 +1051,7 @@ ReservedSpace rs(size, // size alignment, // alignment UseLargePages, // large - NULL, // requested_address - 0); // noacces_prefix + (char *)NULL); // requested_address test_log(" rs.special() == %d", rs.special()); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/virtualspace.hpp --- a/hotspot/src/share/vm/runtime/virtualspace.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,33 +31,29 @@ class ReservedSpace VALUE_OBJ_CLASS_SPEC { friend class VMStructs; - private: + protected: char* _base; size_t _size; size_t _noaccess_prefix; size_t _alignment; bool _special; + private: bool _executable; // ReservedSpace ReservedSpace(char* base, size_t size, size_t alignment, bool special, bool executable); + protected: void initialize(size_t size, size_t alignment, bool large, char* requested_address, - const size_t noaccess_prefix, bool executable); - protected: - // Create protection page at the beginning of the space. - void protect_noaccess_prefix(const size_t size); - public: // Constructor ReservedSpace(); ReservedSpace(size_t size); ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address = NULL, - const size_t noaccess_prefix = 0); + char* requested_address = NULL); ReservedSpace(size_t size, size_t alignment, bool large, bool executable); // Accessors @@ -98,12 +94,23 @@ return last_part(partition_size, alignment()); } -// Class encapsulating behavior specific of memory space reserved for Java heap +// Class encapsulating behavior specific of memory space reserved for Java heap. class ReservedHeapSpace : public ReservedSpace { -public: - // Constructor - ReservedHeapSpace(size_t size, size_t forced_base_alignment, - bool large, char* requested_address); + private: + void try_reserve_heap(size_t size, size_t alignment, bool large, + char *requested_address); + void try_reserve_range(char *highest_start, char *lowest_start, + size_t attach_point_alignment, char *aligned_HBMA, + char *upper_bound, size_t size, size_t alignment, bool large); + void initialize_compressed_heap(const size_t size, size_t alignment, bool large); + // Create protection page at the beginning of the space. + void establish_noaccess_prefix(); + public: + // Constructor. Tries to find a heap that is good for compressed oops. + ReservedHeapSpace(size_t size, size_t forced_base_alignment, bool large); + // Returns the base to be used for compression, i.e. so that null can be + // encoded safely and implicit null checks can work. + char *compressed_oop_base() { return _base - _noaccess_prefix; } }; // Class encapsulating behavior specific memory space for Code diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -2559,6 +2559,8 @@ /**********************/ \ /* frame */ \ /**********************/ \ + NOT_ZERO(PPC64_ONLY(declare_constant(frame::abi_minframe_size))) \ + NOT_ZERO(PPC64_ONLY(declare_constant(frame::entry_frame_locals_size))) \ \ NOT_ZERO(X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))) \ declare_constant(frame::pc_return_offset) \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/runtime/vm_operations.hpp --- a/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -100,6 +100,7 @@ template(RotateGCLog) \ template(WhiteBoxOperation) \ template(ClassLoaderStatsOperation) \ + template(DumpHashtable) \ template(MarkActiveNMethods) \ template(PrintCompileQueue) \ template(PrintCodeList) \ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Tue Jan 20 10:22:44 2015 -0800 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderStats.hpp" +#include "classfile/compactHashtable.hpp" #include "gc_implementation/shared/vmGCOperations.hpp" #include "runtime/javaCalls.hpp" #include "runtime/os.hpp" @@ -56,6 +57,8 @@ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); #endif // INCLUDE_SERVICES DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/utilities/globalDefinitions.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,9 +124,6 @@ extern int BytesPerHeapOop; extern int BitsPerHeapOop; -// Oop encoding heap max -extern uint64_t OopEncodingHeapMax; - const int BitsPerJavaInteger = 32; const int BitsPerJavaLong = 64; const int BitsPerSize_t = size_tSize * BitsPerByte; @@ -195,7 +192,6 @@ return (byte_size + (HeapWordSize-1)) >> LogHeapWordSize; } - const size_t K = 1024; const size_t M = K*K; const size_t G = M*K; @@ -397,8 +393,17 @@ const int KlassAlignmentInBytes = 1 << LogKlassAlignmentInBytes; const int KlassAlignment = KlassAlignmentInBytes / HeapWordSize; -// Klass encoding metaspace max size -const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; +// Maximal size of heap where unscaled compression can be used. Also upper bound +// for heap placement: 4GB. +const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1); +// Maximal size of heap where compressed oops can be used. Also upper bound for heap +// placement for zero based compression algorithm: UnscaledOopHeapMax << LogMinObjAlignmentInBytes. +extern uint64_t OopEncodingHeapMax; + +// Maximal size of compressed class space. Above this limit compression is not possible. +// Also upper bound for placement of zero based class space. (Class space is further limited +// to be < 3G, see arguments.cpp.) +const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlassAlignmentInBytes; // Machine dependent stuff diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2013 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -172,21 +172,21 @@ #define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16) // Some constant sizes used throughout the AIX port -#define SIZE_1K ((uint64_t) 0x400ULL) -#define SIZE_4K ((uint64_t) 0x1000ULL) -#define SIZE_64K ((uint64_t) 0x10000ULL) -#define SIZE_1M ((uint64_t) 0x100000ULL) -#define SIZE_4M ((uint64_t) 0x400000ULL) -#define SIZE_8M ((uint64_t) 0x800000ULL) -#define SIZE_16M ((uint64_t) 0x1000000ULL) -#define SIZE_256M ((uint64_t) 0x10000000ULL) -#define SIZE_1G ((uint64_t) 0x40000000ULL) -#define SIZE_2G ((uint64_t) 0x80000000ULL) -#define SIZE_4G ((uint64_t) 0x100000000ULL) -#define SIZE_16G ((uint64_t) 0x400000000ULL) -#define SIZE_32G ((uint64_t) 0x800000000ULL) -#define SIZE_64G ((uint64_t) 0x1000000000ULL) -#define SIZE_1T ((uint64_t) 0x10000000000ULL) +#define SIZE_1K ((uint64_t) UCONST64( 0x400)) +#define SIZE_4K ((uint64_t) UCONST64( 0x1000)) +#define SIZE_64K ((uint64_t) UCONST64( 0x10000)) +#define SIZE_1M ((uint64_t) UCONST64( 0x100000)) +#define SIZE_4M ((uint64_t) UCONST64( 0x400000)) +#define SIZE_8M ((uint64_t) UCONST64( 0x800000)) +#define SIZE_16M ((uint64_t) UCONST64( 0x1000000)) +#define SIZE_256M ((uint64_t) UCONST64( 0x10000000)) +#define SIZE_1G ((uint64_t) UCONST64( 0x40000000)) +#define SIZE_2G ((uint64_t) UCONST64( 0x80000000)) +#define SIZE_4G ((uint64_t) UCONST64( 0x100000000)) +#define SIZE_16G ((uint64_t) UCONST64( 0x400000000)) +#define SIZE_32G ((uint64_t) UCONST64( 0x800000000)) +#define SIZE_64G ((uint64_t) UCONST64( 0x1000000000)) +#define SIZE_1T ((uint64_t) UCONST64(0x10000000000)) #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/TEST.groups Tue Jan 20 10:22:44 2015 -0800 @@ -145,6 +145,7 @@ gc/survivorAlignment \ runtime/InternalApi/ThreadCpuTimesDeadlock.java \ serviceability/threads/TestFalseDeadLock.java \ + compiler/codecache/jmx # Compact 2 adds full VM tests compact2 = \ @@ -413,6 +414,12 @@ gc/ \ -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java +hotspot_gc_closed = \ + sanity/ExecuteInternalVMTests.java + +hotspot_gc_gcold = \ + stress/gc/TestGCOld.java + hotspot_runtime = \ runtime/ \ -runtime/6888954/vmerrors.sh \ @@ -444,6 +451,8 @@ :hotspot_compiler_3 \ :hotspot_compiler_closed \ :hotspot_gc \ + :hotspot_gc_closed \ + :hotspot_gc_gcold \ :hotspot_runtime \ :hotspot_runtime_closed \ :hotspot_serviceability diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7173584 + * @summary arraycopy as macro node + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArrayCopyMacro + * + */ + +public class TestArrayCopyMacro { + static class A { + } + + // In its own method so profiling reports both branches taken + static Object m2(Object o1, Object o2, int i) { + if (i == 4) { + return o1; + } + return o2; + } + + static Object m1(A[] src, Object dest) { + int i = 1; + + // won't be optimized out until after parsing + for (; i < 3; i *= 4) { + } + dest = m2(new A[10], dest, i); + + // dest is new array here but C2 picks the "disjoint" stub + // only if stub to call is decided after parsing + System.arraycopy(src, 0, dest, 0, 10); + return dest; + } + + public static void main(String[] args) { + A[] array_src = new A[10]; + + for (int i = 0; i < array_src.length; i++) { + array_src[i] = new A(); + } + + for (int i = 0; i < 20000; i++) { + m2(null, null, 0); + } + + for (int i = 0; i < 20000; i++) { + Object[] array_dest = (Object[])m1(array_src, null); + + for (int j = 0; j < array_src.length; j++) { + if (array_dest[j] != array_src[j]) { + throw new RuntimeException("copy failed at index " + j + " src = " + array_src[j] + " dest = " + array_dest[j]); + } + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java --- a/hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8055910 - * @summary Arrays.copyOf doesn't perform subtype check - * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArrayOfNoTypeCheck - * - */ - -import java.util.Arrays; - -public class TestArrayOfNoTypeCheck { - - static class A { - } - - static class B extends A { - } - - static B[] test(A[] arr) { - return Arrays.copyOf(arr, 10, B[].class); - } - - static public void main(String[] args) { - A[] arr = new A[20]; - for (int i = 0; i < 20000; i++) { - test(arr); - } - A[] arr2 = new A[20]; - arr2[0] = new A(); - boolean exception = false; - try { - test(arr2); - } catch (ArrayStoreException ase) { - exception = true; - } - if (!exception) { - throw new RuntimeException("TEST FAILED: ArrayStoreException not thrown"); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8055910 + * @summary Arrays.copyOf doesn't perform subtype check + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestArraysCopyOfNoTypeCheck + * + */ + +import java.util.Arrays; + +public class TestArraysCopyOfNoTypeCheck { + + static class A { + } + + static class B extends A { + } + + static B[] test(A[] arr) { + return Arrays.copyOf(arr, 10, B[].class); + } + + static public void main(String[] args) { + A[] arr = new A[20]; + for (int i = 0; i < 20000; i++) { + test(arr); + } + A[] arr2 = new A[20]; + arr2[0] = new A(); + boolean exception = false; + try { + test(arr2); + } catch (ArrayStoreException ase) { + exception = true; + } + if (!exception) { + throw new RuntimeException("TEST FAILED: ArrayStoreException not thrown"); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6700100 + * @summary small instance clone as loads/stores + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* TestInstanceCloneAsLoadsStores + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode TestInstanceCloneAsLoadsStores + * + */ + +import java.lang.reflect.*; +import java.util.*; + +public class TestInstanceCloneAsLoadsStores { + static class Base implements Cloneable { + void initialize(Class c, int i) { + for (Field f : c.getDeclaredFields()) { + setVal(f, i); + i++; + } + if (c != Base.class) { + initialize(c.getSuperclass(), i); + } + } + + Base() { + initialize(getClass(), 0); + } + + void setVal(Field f, int i) { + try { + if (f.getType() == int.class) { + f.setInt(this, i); + return; + } else if (f.getType() == short.class) { + f.setShort(this, (short)i); + return; + } else if (f.getType() == byte.class) { + f.setByte(this, (byte)i); + return; + } else if (f.getType() == long.class) { + f.setLong(this, i); + return; + } + } catch(IllegalAccessException iae) { + throw new RuntimeException("Getting fields failed"); + } + throw new RuntimeException("unexpected field type"); + } + + int getVal(Field f) { + try { + if (f.getType() == int.class) { + return f.getInt(this); + } else if (f.getType() == short.class) { + return (int)f.getShort(this); + } else if (f.getType() == byte.class) { + return (int)f.getByte(this); + } else if (f.getType() == long.class) { + return (int)f.getLong(this); + } + } catch(IllegalAccessException iae) { + throw new RuntimeException("Setting fields failed"); + } + throw new RuntimeException("unexpected field type"); + } + + boolean fields_equal(Class c, Base o) { + for (Field f : c.getDeclaredFields()) { + if (getVal(f) != o.getVal(f)) { + return false; + } + } + if (c != Base.class) { + return fields_equal(c.getSuperclass(), o); + } + return true; + } + + public boolean equals(Object obj) { + return fields_equal(getClass(), (Base)obj); + } + + String print_fields(Class c, String s) { + for (Field f : c.getDeclaredFields()) { + if (s != "") { + s += "\n"; + } + s = s + f + " = " + getVal(f); + } + if (c != Base.class) { + return print_fields(c.getSuperclass(), s); + } + return s; + } + + public String toString() { + return print_fields(getClass(), ""); + } + + int fields_sum(Class c, int s) { + for (Field f : c.getDeclaredFields()) { + s += getVal(f); + } + if (c != Base.class) { + return fields_sum(c.getSuperclass(), s); + } + return s; + } + + public int sum() { + return fields_sum(getClass(), 0); + } + + } + + static class A extends Base { + int i1; + int i2; + int i3; + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class B extends A { + int i6; + } + + static final class D extends Base { + byte i1; + short i2; + long i3; + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static final class E extends Base { + int i1; + int i2; + int i3; + int i4; + int i5; + int i6; + int i7; + int i8; + int i9; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static final class F extends Base { + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class G extends Base { + int i1; + int i2; + int i3; + + public Object myclone() throws CloneNotSupportedException { + return clone(); + } + } + + static class H extends G { + int i4; + int i5; + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static class J extends Base { + int i1; + int i2; + int i3; + + public Object myclone() throws CloneNotSupportedException { + return clone(); + } + } + + static class K extends J { + int i4; + int i5; + } + + // Should be compiled as loads/stores + static Object m1(D src) throws CloneNotSupportedException { + return src.clone(); + } + + // Should be compiled as adds of src (dest allocation eliminated) + static int m2(D src) throws CloneNotSupportedException { + D dest = (D)src.clone(); + return dest.i1 + dest.i2 + ((int)dest.i3) + dest.i4 + dest.i5; + } + + // Should be compiled as arraycopy stub call (object too large) + static int m3(E src) throws CloneNotSupportedException { + E dest = (E)src.clone(); + return dest.i1 + dest.i2 + dest.i3 + dest.i4 + dest.i5 + + dest.i6 + dest.i7 + dest.i8 + dest.i9; + } + + // Need profiling on src's type to be able to know number of + // fields. Cannot clone as loads/stores if compile doesn't use it. + static Object m4(A src) throws CloneNotSupportedException { + return src.clone(); + } + + // Same as above but should optimize out dest allocation + static int m5(A src) throws CloneNotSupportedException { + A dest = (A)src.clone(); + return dest.i1 + dest.i2 + dest.i3 + dest.i4 + dest.i5; + } + + // Check that if we have no fields to clone we do fine + static Object m6(F src) throws CloneNotSupportedException { + return src.clone(); + } + + // With virtual call to clone: clone inlined from profling which + // gives us exact type of src so we can clone it with + // loads/stores. + static G m7(G src) throws CloneNotSupportedException { + return (G)src.myclone(); + } + + // Virtual call to clone but single target: exact type unknown, + // clone intrinsic uses profiling to determine exact type and + // clone with loads/stores. + static J m8(J src) throws CloneNotSupportedException { + return (J)src.myclone(); + } + + final HashMap tests = new HashMap<>(); + { + for (Method m : this.getClass().getDeclaredMethods()) { + if (m.getName().matches("m[0-9]+")) { + assert(Modifier.isStatic(m.getModifiers())) : m; + tests.put(m.getName(), m); + } + } + } + + boolean success = true; + + void doTest(Base src, String name) throws Exception { + Method m = tests.get(name); + + for (int i = 0; i < 20000; i++) { + boolean failure = false; + Base res = null; + int s = 0; + if (m.getReturnType().isPrimitive()) { + s = (int)m.invoke(null, src); + failure = (s != src.sum()); + } else { + res = (Base)m.invoke(null, src); + failure = !res.equals(src); + } + if (failure) { + System.out.println("Test " + name + " failed"); + System.out.println("source: "); + System.out.println(src); + System.out.println("result: "); + if (m.getReturnType().isPrimitive()) { + System.out.println(s); + } else { + System.out.println(res); + } + success = false; + break; + } + } + } + + public static void main(String[] args) throws Exception { + + TestInstanceCloneAsLoadsStores test = new TestInstanceCloneAsLoadsStores(); + + A a = new A(); + B b = new B(); + D d = new D(); + E e = new E(); + F f = new F(); + G g = new G(); + H h = new H(); + J j = new J(); + K k = new K(); + + test.doTest(d, "m1"); + test.doTest(d, "m2"); + test.doTest(e, "m3"); + test.doTest(a, "m4"); + test.doTest(a, "m5"); + test.doTest(f, "m6"); + test.doTest(g, "m7"); + test.doTest(k, "m8"); + + if (!test.success) { + throw new RuntimeException("some tests failed"); + } + + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/ciReplay/TestSA.sh --- a/hotspot/test/compiler/ciReplay/TestSA.sh Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/ciReplay/TestSA.sh Tue Jan 20 10:22:44 2015 -0800 @@ -26,7 +26,7 @@ ## ## @test ## @bug 8011675 -## @ignore 8031978 +## @ignore 8029528 ## @summary testing of ciReplay with using generated by SA replay.txt ## @author igor.ignatyev@oracle.com ## @run shell TestSA.sh @@ -69,7 +69,6 @@ echo "dumpreplaydata -a > ${replay_data}" | \ ${JAVA} ${TESTOPTS} \ - -cp ${TESTJAVA}${FS}lib${FS}sa-jdi.jar \ sun.jvm.hotspot.CLHSDB ${JAVA} ${core_file} if [ ! -s ${replay_data} ] diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/ciReplay/common.sh --- a/hotspot/test/compiler/ciReplay/common.sh Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/ciReplay/common.sh Tue Jan 20 10:22:44 2015 -0800 @@ -263,10 +263,10 @@ dir=`dirname $core_with_dir` file=`basename $core_with_dir` # add /core. core - core_locations="'$core_with_dir' '$file'" + core_locations='$core_with_dir' '$file' if [ -n "${core_with_pid}" ] then - core_locations="$core_locations '$core_with_pid' '$dir${FS}$core_with_pid'" + core_locations=$core_locations '$core_with_pid' '$dir${FS}$core_with_pid' fi fi diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * @test + * @bug 8015774 + * @summary Verify SegmentedCodeCache option's processing + * @library /testlibrary /../../test/lib + * @build TestSegmentedCodeCacheOption com.oracle.java.testlibrary.* + * @run main TestSegmentedCodeCacheOption + */ +public class TestSegmentedCodeCacheOption { + private static final String INT_MODE = "-Xint"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String USE_SEGMENTED_CODE_CACHE + = CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + true); + private static final long THRESHOLD_CC_SIZE_VALUE + = CodeCacheOptions.mB(240); + private static final long BELOW_THRESHOLD_CC_SIZE + = THRESHOLD_CC_SIZE_VALUE - CodeCacheOptions.mB(1); + private static final String[] UNEXPECTED_MESSAGES = new String[] { + ".*" + SEGMENTED_CODE_CACHE + ".*" + }; + + + private static enum TestCase { + JVM_STARTUP { + @Override + public void run() throws Throwable { + // There should be no errors when we're trying to enable SCC ... + String testCaseWarningMessage = "JVM output should not contain " + + "any warnings related to " + SEGMENTED_CODE_CACHE; + String testCaseExitCodeMessage = "JVM should start without any " + + "issues with " + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE); + // ... and when we're trying to enable it w/o TieredCompilation + testCaseExitCodeMessage = "Disabled tiered compilation should " + + "not cause startup failure w/ " + + USE_SEGMENTED_CODE_CACHE; + + CommandLineOptionTest.verifySameJVMStartup( + /* expectedMessages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, USE_SEGMENTED_CODE_CACHE, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // ... and even w/ Xint. + testCaseExitCodeMessage = "It should be possible to use " + + USE_SEGMENTED_CODE_CACHE + " in interpreted mode " + + "without any errors."; + + CommandLineOptionTest.verifyJVMStartup( + /* expected messages */ null, UNEXPECTED_MESSAGES, + testCaseExitCodeMessage, testCaseWarningMessage, + ExitCode.OK, false, INT_MODE, USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_GENERIC { + @Override + public void run() throws Throwable { + // SCC is disabled w/o TieredCompilation by default + String errorMessage = SEGMENTED_CODE_CACHE + + " should be disabled by default when tiered " + + "compilation is disabled"; + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false)); + // SCC is disabled by default when ReservedCodeCacheSize is too + // small + errorMessage = String.format("%s should be disabled bu default " + + "when %s value is too small.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "false", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE)); + // SCC could be explicitly enabled w/ Xint + errorMessage = String.format("It should be possible to " + + "explicitly enable %s in interpreted mode.", + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValue(SEGMENTED_CODE_CACHE, + "true", errorMessage, false, INT_MODE, + USE_SEGMENTED_CODE_CACHE); + // SCC could be explicitly enabled w/o TieredCompilation and w/ + // small ReservedCodeCacheSize value + errorMessage = String.format("It should be possible to " + + "explicitly enable %s with small %s and " + + "disabled tiered comp.", SEGMENTED_CODE_CACHE, + BlobType.All.sizeOptionName); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, false), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + BELOW_THRESHOLD_CC_SIZE), + USE_SEGMENTED_CODE_CACHE); + } + }, + OPTION_VALUES_SERVER_SPECIFIC { + @Override + public boolean isApplicable() { + return Platform.isServer() && Platform.isTieredSupported(); + } + + @Override + public void run() throws Throwable { + // SCC is enabled by default when TieredCompilation is on and + // ReservedCodeCacheSize is large enough + String errorMessage = String.format("Large enough %s and " + + "enabled tiered compilation should enable %s " + + "by default.", BlobType.All.sizeOptionName, + SEGMENTED_CODE_CACHE); + + CommandLineOptionTest.verifyOptionValueForSameVM( + SEGMENTED_CODE_CACHE, "true", errorMessage, + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, + THRESHOLD_CC_SIZE_VALUE), + CommandLineOptionTest.prepareBooleanFlag( + TIERED_COMPILATION, true)); + } + }; + + TestCase() { + } + + public boolean isApplicable() { + return true; + } + + public abstract void run() throws Throwable; + } + + public static void main(String args[]) throws Throwable { + for (TestCase testCase : TestCase.values()) { + if (testCase.isApplicable()) { + System.out.println("Running test case: " + testCase.name()); + testCase.run(); + } else { + System.out.println("Test case skipped: " + testCase.name()); + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that NonNMethodCodeHeapSize smaller than + * CodeCacheMinimumUseSpace cause JVM startup failure. + */ +public class CodeCacheFreeSpaceRunner implements CodeCacheCLITestCase.Runner { + private static final String CC_MIN_USE_SPACE = "CodeCacheMinimumUseSpace"; + private static final String TOO_SMALL_NMETHOD_CH_ERROR + = "Invalid NonNMethodCodeHeapSize.*"; + private static final long MULTIPLIER = Platform.isDebugBuild() ? 3L : 1L; + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + long ccMinUseSpace = ((options.nonNmethods - 1) / MULTIPLIER + 1); + + String exitCodeErrorMessage = String.format("JVM startup should fail " + + "if %s's value lower then %s.", + BlobType.NonNMethod.sizeOptionName, CC_MIN_USE_SPACE); + String vmOutputErrorMessage = String.format("JVM's output should " + + "contain appropriate error message when %s lower " + + "then %s.", BlobType.NonNMethod.sizeOptionName, + CC_MIN_USE_SPACE); + + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ TOO_SMALL_NMETHOD_CH_ERROR }, + /* unexpected messages */ null, + exitCodeErrorMessage, vmOutputErrorMessage, ExitCode.FAIL, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareNumericFlag( + CC_MIN_USE_SPACE, ccMinUseSpace + 1))); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +/** + * Test case runner aimed to verify that all four options related to code cache + * sizing have correct values. + */ +public class GenericCodeHeapSizeRunner implements CodeCacheCLITestCase.Runner { + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = options.mapOptions(testCaseDescription.involvedCodeHeaps); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.All.sizeOptionName, + Long.toString(expectedValues.reserved), + String.format("%s should have value %d.", + BlobType.All.sizeOptionName, expectedValues.reserved), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.NonNMethod.sizeOptionName, + Long.toString(expectedValues.nonNmethods), + String.format("%s should have value %d.", + BlobType.NonNMethod.sizeOptionName, + expectedValues.nonNmethods), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodNonProfiled.sizeOptionName, + Long.toString(expectedValues.nonProfiled), + String.format("%s should have value %d.", + BlobType.MethodNonProfiled.sizeOptionName, + expectedValues.nonProfiled), + testCaseDescription.getTestOptions(options)); + + CommandLineOptionTest.verifyOptionValueForSameVM( + BlobType.MethodProfiled.sizeOptionName, + Long.toString(expectedValues.profiled), + String.format("%s should have value %d.", + BlobType.MethodProfiled.sizeOptionName, + expectedValues.profiled), + testCaseDescription.getTestOptions(options)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import common.CodeCacheCLITestCase; +import common.CodeCacheOptions; +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; +import java.util.Random; + +/** + * Test case runner aimed to verify option's consistency. + */ +public class JVMStartupRunner implements CodeCacheCLITestCase.Runner { + private static final String INCONSISTENT_CH_SIZES_ERROR + = "Invalid code heap sizes.*"; + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + // Everything should be fine when + // sum(all code heap sizes) == reserved CC size + CommandLineOptionTest.verifySameJVMStartup(/* expected messages */ null, + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + "JVM startup should not fail with consistent code heap sizes", + "JVM output should not contain warning about inconsistent code " + + "heap sizes", ExitCode.OK, options.prepareOptions()); + + verifySingleInconsistentValue(options); + verifyAllInconsistentValues(options); + } + + /** + * Verifies that if at least one of three options will have value, such + * that sum of all three values will be inconsistent, then JVM startup will + * fail. + */ + private static void verifySingleInconsistentValue(CodeCacheOptions options) + throws Throwable { + verifyHeapSizesSum(options.reserved, + scaleCodeHeapSize(options.profiled), options.nonProfiled, + options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + scaleCodeHeapSize(options.nonProfiled), options.nonNmethods); + verifyHeapSizesSum(options.reserved, options.profiled, + options.nonProfiled, scaleCodeHeapSize(options.nonNmethods)); + } + + /** + * Verifies that if all three options will have values such that their sum + * is inconsistent with ReservedCodeCacheSize value, then JVM startup will + * fail. + */ + private static void verifyAllInconsistentValues(CodeCacheOptions options) + throws Throwable { + long profiled = options.profiled; + long nonProfiled = options.nonProfiled; + long nonNMethods = options.nonNmethods; + + while (options.reserved == profiled + nonProfiled + nonNMethods) { + profiled = scaleCodeHeapSize(profiled); + nonProfiled = scaleCodeHeapSize(nonProfiled); + nonNMethods = scaleCodeHeapSize(nonNMethods); + } + + verifyHeapSizesSum(options.reserved, profiled, nonProfiled, + nonNMethods); + } + + private static void verifyHeapSizesSum(long reserved, long profiled, + long nonProfiled, long nonNmethods) throws Throwable { + // JVM startup expected to fail when + // sum(all code heap sizes) != reserved CC size + CommandLineOptionTest.verifySameJVMStartup( + new String[]{ INCONSISTENT_CH_SIZES_ERROR }, + /* unexpected messages */ null, + "JVM startup should fail with inconsistent code heap size.", + "JVM output should contain appropriate error message of code " + + "heap sizes are inconsistent", + ExitCode.FAIL, + CommandLineOptionTest.prepareBooleanFlag( + CodeCacheOptions.SEGMENTED_CODE_CACHE, true), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods)); + } + + /** + * Returns {@code unscaledSize} value scaled by a random factor from + * range (1, 2). If {@code unscaledSize} is not 0, then this + * method will return value that won't be equal to {@code unscaledSize}. + * + * @param unscaledSize The value to be scaled. + * @return {@code unscaledSize} value scaled by a factor from range (1, 2). + */ + private static long scaleCodeHeapSize(long unscaledSize) { + Random random = Utils.getRandomInstance(); + + long scaledSize = unscaledSize; + while (scaledSize == unscaledSize && unscaledSize != 0) { + float scale = 1.0f + random.nextFloat(); + scaledSize = (long) Math.ceil(scale * unscaledSize); + } + return scaledSize; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package codeheapsize; + +import com.oracle.java.testlibrary.Platform; +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @bug 8015774 + * @summary Verify processing of options related to code heaps sizing. + * @library /testlibrary .. /../../test/lib + * @build TestCodeHeapSizeOptions com.oracle.java.testlibrary.* codeheapsize.* + * common.* + * @run main/timeout=240 codeheapsize.TestCodeHeapSizeOptions + */ +public class TestCodeHeapSizeOptions extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase JVM_STARTUP + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented, + EnumSet.noneOf(BlobType.class)), + new JVMStartupRunner()); + + private static final CodeCacheCLITestCase CODE_CACHE_FREE_SPACE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> options.segmented + && Platform.isDebugBuild(), + EnumSet.noneOf(BlobType.class)), + new CodeCacheFreeSpaceRunner()); + + private static final GenericCodeHeapSizeRunner GENERIC_RUNNER + = new GenericCodeHeapSizeRunner(); + + private TestCodeHeapSizeOptions() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + GENERIC_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + GENERIC_RUNNER), + JVM_STARTUP, + CODE_CACHE_FREE_SPACE); + } + + public static void main(String args[]) throws Throwable { + new TestCodeHeapSizeOptions().runTestCases(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +/** + * Base for code cache related command line options tests. + */ +public class CodeCacheCLITestBase { + public static final CodeCacheOptions[] OPTIONS_SET + = new CodeCacheOptions[] { + new CodeCacheOptions(CodeCacheOptions.mB(60), + CodeCacheOptions.mB(20), CodeCacheOptions.mB(20), + CodeCacheOptions.mB(20)), + new CodeCacheOptions(CodeCacheOptions.mB(200), + CodeCacheOptions.mB(75), CodeCacheOptions.mB(75), + CodeCacheOptions.mB(50)), + new CodeCacheOptions(CodeCacheOptions.mB(300), + CodeCacheOptions.mB(100), CodeCacheOptions.mB(100), + CodeCacheOptions.mB(100)), + new CodeCacheOptions(CodeCacheOptions.mB(60)), + new CodeCacheOptions(CodeCacheOptions.mB(200)), + new CodeCacheOptions(CodeCacheOptions.mB(300)) + }; + + private final CodeCacheCLITestCase[] testCases; + private final CodeCacheOptions[] options; + + public CodeCacheCLITestBase(CodeCacheOptions[] options, + CodeCacheCLITestCase... testCases) { + this.testCases = testCases; + this.options = options; + } + + protected void runTestCases() throws Throwable { + for (CodeCacheCLITestCase testCase : testCases) { + for (CodeCacheOptions opts : options) { + testCase.run(opts); + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import com.oracle.java.testlibrary.Platform; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.function.Function; + +/** + * Code cache related command line option test case consisting of description + * of code heaps used during test case run and additional options that should + * be passed to JVM and runner aimed to perform actual testing based on the + * description. + */ +public class CodeCacheCLITestCase { + private static final Function ONLY_SEGMENTED + = options -> options.segmented; + private static final Function SEGMENTED_SERVER + = ONLY_SEGMENTED.andThen(isSegmented -> isSegmented + && Platform.isServer() && Platform.isTieredSupported()); + private static final String USE_INT_MODE = "-Xint"; + private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + private static final String TIERED_COMPILATION = "TieredCompilation"; + private static final String TIERED_STOP_AT = "TieredStopAtLevel"; + + private final Description description; + private final Runner runner; + + public CodeCacheCLITestCase(Description description, Runner runner) { + this.description = description; + this.runner = runner; + } + + public final void run(CodeCacheOptions options) throws Throwable { + if (description.isApplicable(options)) { + runner.run(description, options); + } + } + + public enum CommonDescriptions { + /** + * Verifies that in interpreted mode PrintCodeCache output contains + * only NonNMethod code heap. + */ + INT_MODE(ONLY_SEGMENTED, EnumSet.of(BlobType.NonNMethod), USE_INT_MODE), + /** + * Verifies that with disabled SegmentedCodeCache PrintCodeCache output + * contains only CodeCache's entry. + */ + NON_SEGMENTED(options -> !options.segmented, EnumSet.of(BlobType.All), + CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE, + false)), + /** + * Verifies that with disabled tiered compilation and enabled segmented + * code cache PrintCodeCache output does not contain information about + * profiled-nmethods heap and non-segmented CodeCache. + */ + NON_TIERED(ONLY_SEGMENTED, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + false)), + /** + * Verifies that with TieredStopAtLevel=0 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_0(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 0)), + /** + * Verifies that with TieredStopAtLevel=1 PrintCodeCache output will + * contain information about non-nmethods and non-profiled nmethods + * heaps only. + */ + TIERED_LEVEL_1(SEGMENTED_SERVER, + EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 1)), + /** + * Verifies that with TieredStopAtLevel=4 PrintCodeCache output will + * contain information about all three code heaps. + */ + TIERED_LEVEL_4(SEGMENTED_SERVER, + EnumSet.complementOf(EnumSet.of(BlobType.All)), + CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION, + true), + CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 4)); + + CommonDescriptions(Function predicate, + EnumSet involvedCodeHeaps, + String... additionalOptions) { + this.description = new Description(predicate, + involvedCodeHeaps, additionalOptions); + } + + + public final Description description; + } + + public static class Description { + public final EnumSet involvedCodeHeaps; + private final String[] testCaseSpecificOptions; + private final Function predicate; + + public Description(Function predicate, + EnumSet involvedCodeHeaps, + String... testCaseSpecificOptions) { + this.involvedCodeHeaps = involvedCodeHeaps; + this.testCaseSpecificOptions = testCaseSpecificOptions; + this.predicate = predicate; + } + + public boolean isApplicable(CodeCacheOptions options) { + return predicate.apply(options); + } + + public CodeCacheOptions expectedValues(CodeCacheOptions options) { + return options.mapOptions(involvedCodeHeaps); + } + + public String[] getTestOptions(CodeCacheOptions codeCacheOptions, + String... additionalOptions) { + List options = new LinkedList<>(); + Collections.addAll(options, testCaseSpecificOptions); + Collections.addAll(options, additionalOptions); + return codeCacheOptions.prepareOptions( + options.toArray(new String[options.size()])); + } + } + + public static interface Runner { + public void run(Description testCaseDescription, + CodeCacheOptions options) throws Throwable; + } +} + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import sun.hotspot.code.BlobType; +import java.util.Arrays; + +public class CodeCacheInfoFormatter { + private static final String DEFAULT_SIZE_FORMAT = "[0-9]+Kb"; + private BlobType heap = null; + private String size = DEFAULT_SIZE_FORMAT; + private String used = DEFAULT_SIZE_FORMAT; + private String maxUsed = DEFAULT_SIZE_FORMAT; + private String free = DEFAULT_SIZE_FORMAT; + + public static CodeCacheInfoFormatter forHeap(BlobType heap) { + return new CodeCacheInfoFormatter(heap); + } + + public static String[] forHeaps(BlobType... heaps) { + return Arrays.stream(heaps) + .map(CodeCacheInfoFormatter::forHeap) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + } + + private static String formatSize(long suffix) { + return String.format("%dKb", suffix / 1024); + } + + private CodeCacheInfoFormatter(BlobType heap) { + this.heap = heap; + } + + public CodeCacheInfoFormatter withSize(long size) { + this.size = CodeCacheInfoFormatter.formatSize(size); + return this; + } + + public CodeCacheInfoFormatter withUsed(long used) { + this.used = CodeCacheInfoFormatter.formatSize(used); + return this; + } + + public CodeCacheInfoFormatter withMaxUsed(long maxUsed) { + this.maxUsed = CodeCacheInfoFormatter.formatSize(maxUsed); + return this; + } + + public CodeCacheInfoFormatter withFree(long free) { + this.free = CodeCacheInfoFormatter.formatSize(free); + return this; + } + + public String getInfoString() { + return String.format("%s: size=%s used=%s max_used=%s free=%s", + heap.beanName, size, used, maxUsed, free); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common; + +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import sun.hotspot.code.BlobType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; + +public class CodeCacheOptions { + public static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache"; + + private static final EnumSet NON_SEGMENTED_HEAPS + = EnumSet.of(BlobType.All); + private static final EnumSet ALL_SEGMENTED_HEAPS + = EnumSet.complementOf(NON_SEGMENTED_HEAPS); + private static final EnumSet SEGMENTED_HEAPS_WO_PROFILED + = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled); + private static final EnumSet ONLY_NON_METHODS_HEAP + = EnumSet.of(BlobType.NonNMethod); + + public final long reserved; + public final long nonNmethods; + public final long nonProfiled; + public final long profiled; + public final boolean segmented; + + public static long mB(long val) { + return CodeCacheOptions.kB(val) * 1024L; + } + + public static long kB(long val) { + return val * 1024L; + } + + public CodeCacheOptions(long reserved) { + this.reserved = reserved; + this.nonNmethods = 0; + this.nonProfiled = 0; + this.profiled = 0; + this.segmented = false; + } + + public CodeCacheOptions(long reserved, long nonNmethods, long nonProfiled, + long profiled) { + this.reserved = reserved; + this.nonNmethods = nonNmethods; + this.nonProfiled = nonProfiled; + this.profiled = profiled; + this.segmented = true; + } + + public long sizeForHeap(BlobType heap) { + switch (heap) { + case All: + return this.reserved; + case NonNMethod: + return this.nonNmethods; + case MethodNonProfiled: + return this.nonProfiled; + case MethodProfiled: + return this.profiled; + default: + throw new Error("Unknown heap: " + heap.name()); + } + } + + public String[] prepareOptions(String... additionalOptions) { + List options = new ArrayList<>(); + Collections.addAll(options, additionalOptions); + Collections.addAll(options, + CommandLineOptionTest.prepareBooleanFlag( + SEGMENTED_CODE_CACHE, segmented), + CommandLineOptionTest.prepareNumericFlag( + BlobType.All.sizeOptionName, reserved)); + + if (segmented) { + Collections.addAll(options, + CommandLineOptionTest.prepareNumericFlag( + BlobType.NonNMethod.sizeOptionName, nonNmethods), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodNonProfiled.sizeOptionName, + nonProfiled), + CommandLineOptionTest.prepareNumericFlag( + BlobType.MethodProfiled.sizeOptionName, profiled)); + } + return options.toArray(new String[options.size()]); + } + + public CodeCacheOptions mapOptions(EnumSet involvedCodeHeaps) { + if (involvedCodeHeaps.isEmpty() + || involvedCodeHeaps.equals(NON_SEGMENTED_HEAPS) + || involvedCodeHeaps.equals(ALL_SEGMENTED_HEAPS)) { + return this; + } else if (involvedCodeHeaps.equals(SEGMENTED_HEAPS_WO_PROFILED)) { + return new CodeCacheOptions(reserved, nonNmethods, + profiled + nonProfiled, 0L); + } else if (involvedCodeHeaps.equals(ONLY_NON_METHODS_HEAP)) { + return new CodeCacheOptions(reserved, nonNmethods + profiled + + nonProfiled, 0L, 0L); + } else { + throw new Error("Test bug: unexpected set of code heaps involved " + + "into test."); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package printcodecache; + +import com.oracle.java.testlibrary.ExitCode; +import com.oracle.java.testlibrary.cli.CommandLineOptionTest; +import common.CodeCacheCLITestCase; +import common.CodeCacheInfoFormatter; +import common.CodeCacheOptions; +import sun.hotspot.code.BlobType; + +import java.util.EnumSet; +import java.util.stream.Collectors; + +/** + * Runner implementation aimed to verify PrintCodeCache output. + */ +public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner { + private final boolean printCodeCache; + + public PrintCodeCacheRunner(boolean printCodeCache) { + this.printCodeCache = printCodeCache; + } + + public PrintCodeCacheRunner() { + this(true); + } + + @Override + public void run(CodeCacheCLITestCase.Description testCaseDescription, + CodeCacheOptions options) throws Throwable { + CodeCacheOptions expectedValues + = testCaseDescription.expectedValues(options); + + String[] expectedMessages + = testCaseDescription.involvedCodeHeaps.stream() + .map(heap -> CodeCacheInfoFormatter.forHeap(heap) + .withSize(expectedValues.sizeForHeap(heap))) + .map(CodeCacheInfoFormatter::getInfoString) + .toArray(String[]::new); + + EnumSet unexpectedHeapsSet + = EnumSet.complementOf(testCaseDescription.involvedCodeHeaps); + + String[] unexpectedMessages = CodeCacheInfoFormatter.forHeaps( + unexpectedHeapsSet.toArray( + new BlobType[unexpectedHeapsSet.size()])); + + String description = String.format("JVM output should contain entries " + + "for following code heaps: [%s] and should not contain " + + "entries for following code heaps: [%s].", + testCaseDescription.involvedCodeHeaps.stream() + .map(BlobType::name) + .collect(Collectors.joining(", ")), + unexpectedHeapsSet.stream() + .map(BlobType::name) + .collect(Collectors.joining(", "))); + + CommandLineOptionTest.verifySameJVMStartup(expectedMessages, + unexpectedMessages, "JVM startup failure is not expected, " + + "since all options have allowed values", description, + ExitCode.OK, + testCaseDescription.getTestOptions(options, + CommandLineOptionTest.prepareBooleanFlag( + "PrintCodeCache", printCodeCache))); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package printcodecache; + +import common.CodeCacheCLITestBase; +import common.CodeCacheCLITestCase; +import sun.hotspot.code.BlobType; +import java.util.EnumSet; +/** + * @test + * @bug 8015774 + * @summary Verify that PrintCodeCache option print correct information. + * @library /testlibrary .. /../../test/lib + * @build TestPrintCodeCacheOption com.oracle.java.testlibrary.* + * printcodecache.* common.* + * @run main/timeout=240 printcodecache.TestPrintCodeCacheOption + */ +public class TestPrintCodeCacheOption extends CodeCacheCLITestBase { + private static final CodeCacheCLITestCase DISABLED_PRINT_CODE_CACHE + = new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description( + options -> true, EnumSet.noneOf(BlobType.class)), + new PrintCodeCacheRunner(false)); + + private static final CodeCacheCLITestCase.Runner DEFAULT_RUNNER + = new PrintCodeCacheRunner(); + + private TestPrintCodeCacheOption() { + super(CodeCacheCLITestBase.OPTIONS_SET, + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.INT_MODE.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_SEGMENTED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.NON_TIERED.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_0.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_1.description, + DEFAULT_RUNNER), + new CodeCacheCLITestCase(CodeCacheCLITestCase + .CommonDescriptions.TIERED_LEVEL_4.description, + DEFAULT_RUNNER), + DISABLED_PRINT_CODE_CACHE); + } + + public static void main(String args[]) throws Throwable { + new TestPrintCodeCacheOption().runTestCases(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.JDKToolFinder; +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.Utils; +import com.oracle.java.testlibrary.dtrace.DtraceResultsAnalyzer; +import com.oracle.java.testlibrary.dtrace.DtraceRunner; +import java.io.IOException; +import java.lang.reflect.Executable; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/* + * @test SegmentedCodeCacheDtraceTest + * @bug 8015774 + * @requires os.family=="solaris" + * @library /testlibrary /compiler/testlibrary /../../test/lib + * @build SegmentedCodeCacheDtraceTestWorker + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * SegmentedCodeCacheDtraceTest + * @summary testing of dtrace for segmented code cache + */ +public class SegmentedCodeCacheDtraceTest { + + private static final String WORKER_CLASS_NAME + = SegmentedCodeCacheDtraceTestWorker.class.getName(); + private static final String JAVA_OPTS = " -XX:+DTraceMethodProbes " + + "-Xbootclasspath/a:" + System.getProperty("test.classes") + " " + + "-XX:+UnlockDiagnosticVMOptions " + + "-XX:+WhiteBoxAPI -XX:+SegmentedCodeCache " + + "-XX:CompileCommand=compileonly," + + WORKER_CLASS_NAME + "::* " + + " -classpath " + System.getProperty("test.class.path") + " " + + String.join(" ", Utils.getTestJavaOpts()); + private static final String DTRACE_SCRIPT + = "SegmentedCodeCacheDtraceTestScript.d"; + private static final List MLIST = + SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST; + private static final int WORKER_METHODS_COUNT = MLIST.size(); + + private void runTest(TestCombination tc) { + String params = MLIST.stream() + .map(Executable::getName) + .map(x -> tc.data.get(x).compileLevel + " " + tc.data.get(x).isInlined) + .collect(Collectors.joining(" ")); + DtraceRunner runner = new DtraceRunner(); + runner.runDtrace(JDKToolFinder.getTestJDKTool("java"), JAVA_OPTS, + WORKER_CLASS_NAME, params, Paths.get(System.getProperty("test.src"), + DTRACE_SCRIPT).toString(), + DtraceRunner.PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION, + new SegmentedCodeCacheDtraceResultsAnalyzer()); + } + + private static TestCombination generateUniqueCombination( + int[] availableLevels, Set combinations) { + int len = availableLevels.length; + /* first, check if we're out of combinations. */ + int maxCombinationsCount + = (1 << WORKER_METHODS_COUNT) + * (int) Math.pow(len, WORKER_METHODS_COUNT); + if (combinations.size() == maxCombinationsCount) { + return null; + } + Random r = Utils.getRandomInstance(); + while (combinations.size() < maxCombinationsCount) { + int levels[] = new int[WORKER_METHODS_COUNT]; + boolean inlines[] = new boolean[WORKER_METHODS_COUNT]; + for (int i = 0; i < WORKER_METHODS_COUNT; i++) { + levels[i] = availableLevels[r.nextInt(len)]; + inlines[i] = r.nextBoolean(); + } + TestCombination tc = new TestCombination(levels, inlines); + if (combinations.add(tc)) { + return tc; + } + } + return null; + } + + public static void main(String args[]) { + int iterations + = Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + if (!DtraceRunner.dtraceAvailable()) { + System.out.println("INFO: There is no dtrace avaiable. Skipping."); + return; + } + int[] availableLevels = CompilerUtils.getAvailableCompilationLevels(); + // adding one more entry(zero) for interpeter + availableLevels + = Arrays.copyOf(availableLevels, availableLevels.length + 1); + Set combinations = new HashSet<>(); + for (int i = 0; i < iterations; i++) { + TestCombination tc + = generateUniqueCombination(availableLevels, combinations); + if (tc == null) { + System.out.println("INFO: no more combinations available"); + return; + } else { + System.out.println("INFO: Running testcase for: " + tc); + new SegmentedCodeCacheDtraceTest().runTest(tc); + } + } + } + + private static class MethodData { + + public final int compileLevel; + public final boolean isInlined; + public final String name; + + public MethodData(String name, int compileLevel, boolean isInlined) { + this.name = name; + this.compileLevel = compileLevel; + this.isInlined = isInlined; + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof MethodData)) { + return false; + } + MethodData md = (MethodData) o; + return md.compileLevel == compileLevel + && md.isInlined == isInlined + && md.name.equals(name); + } + + @Override + public int hashCode() { + return 100 * name.hashCode() + 10 * compileLevel + (isInlined ? 1 : 0); + } + + @Override + public String toString() { + return name + " " + compileLevel + " " + isInlined; + } + } + + private static class TestCombination { + + private final Map data; + + public TestCombination(int compLevels[], boolean inlines[]) { + Map d = new HashMap<>(); + for (int i = 0; i < MLIST.size(); i++) { + d.put(MLIST.get(i).getName(), new MethodData(MLIST.get(i).getName(), + compLevels[i], inlines[i])); + } + data = Collections.unmodifiableMap(d); + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof TestCombination)) { + return false; + } + TestCombination second = (TestCombination) o; + return second.data.equals(data); + } + + @Override + public int hashCode() { + int sum = 0; + for (MethodData md : data.values()) { + sum += md.hashCode(); + } + return sum; + } + + private String getMethodDescString(MethodData md) { + return (md == null) + ? null + : String.format("Method %s compilation level %d and %s", + md.name, md.compileLevel, + md.isInlined ? "inlined" : "not inlined"); + } + + @Override + public String toString() { + return data.values().stream().map(m -> getMethodDescString(m)) + .collect(Collectors.joining(Utils.NEW_LINE, + "Combination: ", "")); + } + } + + private class SegmentedCodeCacheDtraceResultsAnalyzer + implements DtraceResultsAnalyzer { + + private static final int EXPECTED_MATCH_COUNT = 2; + + private final Pattern checkPattern; + + public SegmentedCodeCacheDtraceResultsAnalyzer() { + String workerClassRegExp = "\\s*" + WORKER_CLASS_NAME + "\\."; + String delimeter = "\\(\\)V\\*?" + workerClassRegExp; + String suffix = "test\\(\\)V\\*?" + workerClassRegExp + + "main\\(\\[Ljava\\/lang\\/String;\\)V"; + StringBuilder sb = new StringBuilder(workerClassRegExp); + // method order is important, so, going from list tail to head, + // accoring to call order representation in stacktrace + for (int i = MLIST.size() - 1; i > -1; i--) { + sb.append(MLIST.get(i).getName()).append(delimeter); + } + sb.append(suffix); + checkPattern = Pattern.compile(sb.toString()); + /* such pattern match should pass on a stacktrace like + CPU ID FUNCTION:NAME + 0 53573 __1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_:method-entry ustack: + + libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c + SegmentedCodeCacheDtraceTestWorker.baz()V* + SegmentedCodeCacheDtraceTestWorker.bar()V + SegmentedCodeCacheDtraceTestWorker.foo()V* + SegmentedCodeCacheDtraceTestWorker.test()V + SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V + 0xffffffff6b0004b8 + libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c + libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64 + libjvm.so`jni_CallStaticVoidMethod+0x508 + libjli.so`JavaMain+0x584 + libc.so.1`_lwp_start + jstack: + + libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c + SegmentedCodeCacheDtraceTestWorker.baz()V* + SegmentedCodeCacheDtraceTestWorker.bar()V + SegmentedCodeCacheDtraceTestWorker.foo()V* + SegmentedCodeCacheDtraceTestWorker.test()V + SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V + 0xffffffff6b0004b8 + libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c + libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64 + libjvm.so`jni_CallStaticVoidMethod+0x508 + libjli.so`JavaMain+0x584 + libc.so.1`_lwp_start + */ + } + + protected List loadLog(String dtraceOutFile) throws IOException { + return Files.readAllLines(Paths.get(dtraceOutFile)); + } + + @Override + public void analyze(OutputAnalyzer oa, String dtraceOutFilePath) { + oa.shouldHaveExitValue(0); + List dOut; + try { + dOut = loadLog(dtraceOutFilePath); + } catch (IOException e) { + throw new Error("Can't load log", e); + } + StringBuilder allDtraceOutput = new StringBuilder(); + for (String entry : dOut) { + allDtraceOutput.append(entry); + } + int matchCount = getMatchCount(allDtraceOutput.toString()); + Asserts.assertEQ(matchCount, EXPECTED_MATCH_COUNT, + "Unexpected output match amount. expected: " + + EXPECTED_MATCH_COUNT + " but found " + matchCount); + } + + protected int getMatchCount(String source) { + Matcher m = checkPattern.matcher(source); + int matchCount = 0; + while (m.find()) { + matchCount++; + } + return matchCount; + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,33 @@ +#!/usr/sbin/dtrace -s + +/* + Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + This code is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +*/ + +hotspot$target:::method-entry +/ copyinstr(arg3, arg4) == "baz" / +{ + printf("ustack:\n"); + ustack(50, 500); + printf("jstack:\n"); + jstack(); +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Utils; +import java.lang.reflect.Executable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import sun.hotspot.WhiteBox; + +public class SegmentedCodeCacheDtraceTestWorker { + + private static final String METHOD1_NAME = "foo"; + private static final String METHOD2_NAME = "bar"; + private static final String METHOD3_NAME = "baz"; + public static final List TESTED_METHODS_LIST; + private final WhiteBox wb; + private final int compLevels[]; + + static { + List methods = new ArrayList<>(); + try { + // method order is important. Need to place methods in call order, + // to be able to verify results later + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD1_NAME)); + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD2_NAME)); + methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD3_NAME)); + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG: no expected method found", e); + } + TESTED_METHODS_LIST = Collections.unmodifiableList(methods); + } + + protected static final boolean BACKGROUND_COMPILATION + = WhiteBox.getWhiteBox().getBooleanVMFlag("BackgroundCompilation"); + + public static void main(String[] args) { + if (args.length != 2 * TESTED_METHODS_LIST.size()) { + throw new Error("Usage: java " + + " " + + " "); + } else { + int compLevels[] = new int[TESTED_METHODS_LIST.size()]; + boolean inlines[] = new boolean[TESTED_METHODS_LIST.size()]; + for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) { + compLevels[i] = Integer.parseInt(args[2 * i]); + inlines[i] = Boolean.parseBoolean(args[2 * i + 1]); + } + new SegmentedCodeCacheDtraceTestWorker(compLevels, inlines).test(); + } + } + + public SegmentedCodeCacheDtraceTestWorker(int compLevels[], boolean inlines[]) { + wb = WhiteBox.getWhiteBox(); + this.compLevels = Arrays.copyOf(compLevels, compLevels.length); + for (int i = 0; i < compLevels.length; i++) { + if (inlines[i]) { + wb.testSetForceInlineMethod(TESTED_METHODS_LIST.get(i), true); + } else { + wb.testSetDontInlineMethod(TESTED_METHODS_LIST.get(i), true); + } + } + } + + private void waitForCompilation(Executable executable, int compLevel) { + if (compLevel > 0) { + Utils.waitForCondition(() -> wb.isMethodCompiled(executable)); + } + } + + protected void test() { + for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) { + Executable method = TESTED_METHODS_LIST.get(i); + int compLevel = compLevels[i]; + wb.enqueueMethodForCompilation(method, compLevel); + waitForCompilation(method, compLevel); + } + foo(); + } + + public static void foo() { + bar(); + } + + public static void bar() { + baz(); + } + + public static void baz() { + System.out.println("Reached baz method"); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/BeanTypeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/BeanTypeTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryType; +import sun.hotspot.code.BlobType; + +/** + * @test BeanTypeTest + * @library /testlibrary /../../test/lib + * @build BeanTypeTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache BeanTypeTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache BeanTypeTest + * @summary verify types of code cache memory pool bean + */ +public class BeanTypeTest { + + public static void main(String args[]) { + for (BlobType bt : BlobType.getAvailable()) { + Asserts.assertEQ(MemoryType.NON_HEAP, bt.getMemoryPool().getType()); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Utils; +import java.lang.management.MemoryPoolMXBean; +import javax.management.Notification; +import sun.hotspot.WhiteBox; +import sun.hotspot.code.BlobType; +import sun.hotspot.code.CodeBlob; + +public final class CodeCacheUtils { + + /** + * Returns the value to be used for code heap allocation + */ + public static final int ALLOCATION_SIZE + = Integer.getInteger("codecache.allocation.size", 100); + public static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static final long SEGMENT_SIZE + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheSegmentSize"); + public static final long MIN_BLOCK_LENGTH + = WhiteBox.getWhiteBox().getUintxVMFlag("CodeCacheMinBlockLength"); + public static final long MIN_ALLOCATION = SEGMENT_SIZE * MIN_BLOCK_LENGTH; + + private CodeCacheUtils() { + // To prevent from instantiation + } + + public static final void hitUsageThreshold(MemoryPoolMXBean bean, + BlobType btype) { + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + 1); + long usageThresholdCount = bean.getUsageThresholdCount(); + long addr = WB.allocateCodeBlob(1, btype.id); + WB.fullGC(); + Utils.waitForCondition(() + -> bean.getUsageThresholdCount() == usageThresholdCount + 1); + WB.freeCodeBlob(addr); + } + + public static final long getHeaderSize(BlobType btype) { + long addr = WB.allocateCodeBlob(0, btype.id); + int size = CodeBlob.getCodeBlob(addr).size; + WB.freeCodeBlob(addr); + return size; + } + + public static String getPoolNameFromNotification( + Notification notification) { + return ((javax.management.openmbean.CompositeDataSupport) + notification.getUserData()).get("poolName").toString(); + } + + public static boolean isAvailableCodeHeapPoolName(String name) { + return BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .map(MemoryPoolMXBean::getName) + .filter(name::equals) + .findAny().isPresent(); + } + + /** + * A "non-nmethods" code heap is used by interpreter during bytecode + * execution, thus, it can't be predicted if this code heap usage will be + * increased or not. Same goes for 'All'. + * + * @param btype BlobType to be checked + * @return boolean value, true if respective code heap is predictable + */ + public static boolean isCodeHeapPredictable(BlobType btype) { + return btype == BlobType.MethodNonProfiled + || btype == BlobType.MethodProfiled; + } + + public static void disableCollectionUsageThresholds(){ + BlobType.getAvailable().stream() + .map(BlobType::getMemoryPool) + .filter(MemoryPoolMXBean::isCollectionUsageThresholdSupported) + .forEach(b -> b.setCollectionUsageThreshold(0L)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.util.EnumSet; +import sun.hotspot.code.BlobType; + +/** + * @test CodeHeapBeanPresenceTest + * @library /testlibrary /../../test/lib + * @build CodeHeapBeanPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache CodeHeapBeanPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache CodeHeapBeanPresenceTest + * @summary verify CodeHeap bean presence + */ +public class CodeHeapBeanPresenceTest { + + public static void main(String args[]) { + EnumSet shouldBeAvailable = BlobType.getAvailable(); + EnumSet shouldNotBeAvailable + = EnumSet.complementOf(shouldBeAvailable); + for (BlobType btype : shouldBeAvailable) { + Asserts.assertNotNull(btype.getMemoryPool(), + "Can't find memory pool for " + btype.name()); + } + for (BlobType btype : shouldNotBeAvailable) { + Asserts.assertNull(btype.getMemoryPool(), + "Memory pool unexpected for " + btype.name()); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/GetUsageTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import sun.hotspot.code.BlobType; + +/* + * @test GetUsageTest + * @library /testlibrary /../../test/lib + * @build GetUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:CompileCommand=compileonly,null::* + * -XX:-UseCodeCacheFlushing -XX:-MethodFlushing -XX:+SegmentedCodeCache + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI GetUsageTest + * @summary testing of getUsage() for segmented code cache + */ +public class GetUsageTest { + + private final BlobType btype; + private final int allocateSize; + + public GetUsageTest(BlobType btype, int allocSize) { + this.btype = btype; + this.allocateSize = allocSize; + } + + public static void main(String[] args) throws Exception { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + for (int allocSize = 10; allocSize < 100000; allocSize *= 10) { + new GetUsageTest(btype, allocSize).runTest(); + } + } + } + } + + protected final Map getBeanUsages() { + Map beanUsages = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + beanUsages.put(bt.getMemoryPool(), + bt.getMemoryPool().getUsage().getUsed()); + } + return beanUsages; + } + + protected void runTest() { + MemoryPoolMXBean[] predictableBeans = BlobType.getAvailable().stream() + .filter(CodeCacheUtils::isCodeHeapPredictable) + .map(BlobType::getMemoryPool) + .toArray(MemoryPoolMXBean[]::new); + Map initial = getBeanUsages(); + long addr = 0; + try { + addr = CodeCacheUtils.WB.allocateCodeBlob(allocateSize, btype.id); + Map current = getBeanUsages(); + long blockCount = Math.floorDiv(allocateSize + + CodeCacheUtils.getHeaderSize(btype) + + CodeCacheUtils.SEGMENT_SIZE - 1, CodeCacheUtils.SEGMENT_SIZE); + long usageUpperEstimate = Math.max(blockCount, + CodeCacheUtils.MIN_BLOCK_LENGTH) * CodeCacheUtils.SEGMENT_SIZE; + for (MemoryPoolMXBean entry : predictableBeans) { + long diff = current.get(entry) - initial.get(entry); + if (entry.equals(btype.getMemoryPool())) { + Asserts.assertFalse(diff <= 0L || diff > usageUpperEstimate, + String.format("Pool %s usage increase was reported " + + "unexpectedly as increased by %d using " + + "allocation size %d", entry.getName(), + diff, allocateSize)); + } else { + Asserts.assertEQ(diff, 0L, + String.format("Pool %s usage changed unexpectedly while" + + " trying to increase: %s using allocation " + + "size %d", entry.getName(), + btype.getMemoryPool().getName(), allocateSize)); + } + } + } finally { + if (addr != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + btype.getMemoryPool().getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import java.util.ArrayList; +import java.util.List; +import sun.hotspot.code.BlobType; + +/* + * @test InitialAndMaxUsageTest + * @library /testlibrary /../../test/lib + * @build InitialAndMaxUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * InitialAndMaxUsageTest + * @summary testing of initial and max usage + */ +public class InitialAndMaxUsageTest { + + private static final double CACHE_USAGE_COEF = 0.95d; + private final BlobType btype; + private final boolean lowerBoundIsZero; + private final long maxSize; + + public InitialAndMaxUsageTest(BlobType btype) { + this.btype = btype; + this.maxSize = btype.getSize(); + /* Only profiled code cache initial size should be 0, because of + -XX:CompileCommand=compileonly,null::* non-methods might be not empty, + as well as non-profiled methods, because it's used as fallback in + case non-methods is full */ + lowerBoundIsZero = btype == BlobType.MethodProfiled; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new InitialAndMaxUsageTest(btype).runTest(); + } + } + + private void fillWithSize(long size, List blobs) { + long blob; + while ((blob = CodeCacheUtils.WB.allocateCodeBlob(size, btype.id)) + != 0L) { + blobs.add(blob); + } + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialUsage = btype.getMemoryPool().getUsage().getUsed(); + System.out.printf("INFO: trying to test %s of max size %d and initial" + + " usage %d%n", bean.getName(), maxSize, initialUsage); + Asserts.assertLT(initialUsage + headerSize + 1L, maxSize, + "Initial usage is close to total size for " + bean.getName()); + if (lowerBoundIsZero) { + Asserts.assertEQ(initialUsage, 0L, "Unexpected initial usage"); + } + ArrayList blobs = new ArrayList<>(); + long minAllocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + /* now filling code cache with large-sized allocation first, since + lots of small allocations takes too much time, so, just a small + optimization */ + try { + for (int coef = 1000000; coef > 0; coef /= 10) { + fillWithSize(coef * minAllocationUnit, blobs); + } + Asserts.assertGT((double) bean.getUsage().getUsed(), + CACHE_USAGE_COEF * maxSize, String.format("Unable to fill " + + "more than %f of %s. Reported usage is %d ", + CACHE_USAGE_COEF, bean.getName(), + bean.getUsage().getUsed())); + } finally { + for (long entry : blobs) { + CodeCacheUtils.WB.freeCodeBlob(entry); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } + +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/** + * @test ManagerNamesTest + * @library /testlibrary /../../test/lib + * @build ManagerNamesTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache ManagerNamesTest + * * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache ManagerNamesTest + * @summary verify getMemoryManageNames calls in case of segmented code cache + */ +public class ManagerNamesTest { + + private final MemoryPoolMXBean bean; + private final static String POOL_NAME = "CodeCacheManager"; + + public static void main(String args[]) { + for (BlobType btype : BlobType.getAvailable()) { + new ManagerNamesTest(btype).runTest(); + } + } + + public ManagerNamesTest(BlobType btype) { + bean = btype.getMemoryPool(); + } + + protected void runTest() { + String[] names = bean.getMemoryManagerNames(); + Asserts.assertEQ(names.length, 1, + "Unexpected length of MemoryManagerNames"); + Asserts.assertEQ(POOL_NAME, names[0], + "Unexpected value of MemoryManagerName"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryManagerMXBean; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import sun.hotspot.code.BlobType; + +/** + * @test MemoryPoolsPresenceTest + * @library /testlibrary /../../test/lib + * @build MemoryPoolsPresenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache MemoryPoolsPresenceTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache MemoryPoolsPresenceTest + * @summary verify that MemoryManagerMXBean exists for every code cache segment + */ +public class MemoryPoolsPresenceTest { + + private static final String CC_MANAGER = "CodeCacheManager"; + private final Map counters = new HashMap<>(); + + public static void main(String args[]) { + new MemoryPoolsPresenceTest().runTest(); + } + + protected void runTest() { + List beans + = ManagementFactory.getMemoryManagerMXBeans(); + Optional any = beans + .stream() + .filter(bean -> CC_MANAGER.equals(bean.getName())) + .findAny(); + Asserts.assertTrue(any.isPresent(), "Bean not found: " + CC_MANAGER); + MemoryManagerMXBean ccManager = any.get(); + Asserts.assertNotNull(ccManager, "Found null for " + CC_MANAGER); + String names[] = ccManager.getMemoryPoolNames(); + for (String name : names) { + counters.put(name, counters.containsKey(name) + ? counters.get(name) + 1 : 1); + } + for (BlobType btype : BlobType.getAvailable()) { + Asserts.assertEQ(counters.get(btype.getMemoryPool().getName()), 1, + "Found unexpected amount of beans for pool " + + btype.getMemoryPool().getName()); + } + Asserts.assertEQ(BlobType.getAvailable().size(), + counters.keySet().size(), "Unexpected amount of bean names"); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/PeakUsageTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test PeakUsageTest + * @library /testlibrary /../../test/lib + * @build PeakUsageTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* PeakUsageTest + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache + * -XX:CompileCommand=compileonly,null::* PeakUsageTest + * @summary testing of getPeakUsage() and resetPeakUsage for + * segmented code cache + */ +public class PeakUsageTest { + + private final BlobType btype; + + public PeakUsageTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new PeakUsageTest(btype).runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + bean.resetPeakUsage(); + long addr = CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + long newPeakUsage = bean.getPeakUsage().getUsed(); + try { + Asserts.assertEQ(newPeakUsage, bean.getUsage().getUsed(), + "Peak usage does not match usage after allocation for " + + bean.getName()); + } finally { + if (addr != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr); + } + } + Asserts.assertEQ(newPeakUsage, bean.getPeakUsage().getUsed(), + "Code cache peak usage has changed after usage decreased for " + + bean.getName()); + bean.resetPeakUsage(); + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after reset for " + + bean.getName()); + long addr2 = CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + try { + Asserts.assertEQ(bean.getPeakUsage().getUsed(), + bean.getUsage().getUsed(), + "Code cache peak usage is not equal to usage after fresh " + + "allocation for " + bean.getName()); + } finally { + if (addr2 != 0) { + CodeCacheUtils.WB.freeCodeBlob(addr2); + } + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test PoolsIndependenceTest + * @library /testlibrary /../../test/lib + * @build PoolsIndependenceTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache PoolsIndependenceTest + * @summary testing of getUsageThreshold() + */ +public class PoolsIndependenceTest implements NotificationListener { + + private final Map counters; + private final BlobType btype; + private volatile long lastEventTimestamp; + + public PoolsIndependenceTest(BlobType btype) { + counters = new HashMap<>(); + for (BlobType bt : BlobType.getAvailable()) { + counters.put(bt.getMemoryPool().getName(), new AtomicInteger(0)); + } + this.btype = btype; + lastEventTimestamp = 0; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new PoolsIndependenceTest(bt).runTest(); + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + bean.setUsageThreshold(bean.getUsage().getUsed() + 1); + long beginTimestamp = System.currentTimeMillis(); + CodeCacheUtils.WB.allocateCodeBlob( + CodeCacheUtils.ALLOCATION_SIZE, btype.id); + CodeCacheUtils.WB.fullGC(); + /* waiting for expected event to be received plus double the time took + to receive expected event(for possible unexpected) and + plus 1 second in case expected event received (almost)immediately */ + Utils.waitForCondition(() -> { + long currentTimestamp = System.currentTimeMillis(); + int eventsCount + = counters.get(btype.getMemoryPool().getName()).get(); + if (eventsCount > 0) { + if (eventsCount > 1) { + return true; + } + long timeLastEventTook + = beginTimestamp - lastEventTimestamp; + long timeoutValue + = 1000L + beginTimestamp + 3L * timeLastEventTook; + return currentTimestamp > timeoutValue; + } + return false; + }); + for (BlobType bt : BlobType.getAvailable()) { + int expectedNotificationsAmount = bt.equals(btype) ? 1 : 0; + Asserts.assertEQ(counters.get(bt.getMemoryPool().getName()).get(), + expectedNotificationsAmount, String.format("Unexpected " + + "amount of notifications for pool: %s", + bt.getMemoryPool().getName())); + } + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario with %s finished%n", bean.getName()); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + // receiving events from available CodeCache-related beans only + if (counters.get(poolName) != null) { + counters.get(poolName).incrementAndGet(); + lastEventTimestamp = System.currentTimeMillis(); + } + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Utils; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryNotificationInfo; +import java.lang.management.MemoryPoolMXBean; +import javax.management.ListenerNotFoundException; +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import sun.hotspot.code.BlobType; + +/* + * @test ThresholdNotificationsTest + * @library /testlibrary /../../test/lib + * @build ThresholdNotificationsTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * ThresholdNotificationsTest + * @summary testing of getUsageThreshold() + */ +public class ThresholdNotificationsTest implements NotificationListener { + + private final static long WAIT_TIME = 10000L; + private volatile long counter; + private final BlobType btype; + + public static void main(String[] args) { + for (BlobType bt : BlobType.getAvailable()) { + new ThresholdNotificationsTest(bt).runTest(); + } + } + + public ThresholdNotificationsTest(BlobType btype) { + this.btype = btype; + counter = 0L; + CodeCacheUtils.disableCollectionUsageThresholds(); + } + + @Override + public void handleNotification(Notification notification, Object handback) { + String nType = notification.getType(); + String poolName + = CodeCacheUtils.getPoolNameFromNotification(notification); + // consider code cache events only + if (CodeCacheUtils.isAvailableCodeHeapPoolName(poolName)) { + Asserts.assertEQ(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED, + nType, "Unexpected event received: " + nType); + if (poolName.equals(btype.getMemoryPool().getName())) { + counter++; + } + } + } + + protected void runTest() { + int iterationsCount = + Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + MemoryPoolMXBean bean = btype.getMemoryPool(); + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + addNotificationListener(this, null, null); + for (int i = 0; i < iterationsCount; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Asserts.assertTrue( + Utils.waitForCondition( + () -> counter == iterationsCount, WAIT_TIME), + "Couldn't receive expected notifications count"); + try { + ((NotificationEmitter) ManagementFactory.getMemoryMXBean()). + removeNotificationListener(this); + } catch (ListenerNotFoundException ex) { + throw new AssertionError("Can't remove notification listener", ex); + } + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test UsageThresholdExceededSeveralTimesTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * -Dcom.oracle.java.testlibrary.iterations=10 UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit several times + */ diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdExceededTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* + * UsageThresholdExceededTest + * @summary verifying that getUsageThresholdCount() returns correct value + * after threshold has been hit + */ +public class UsageThresholdExceededTest { + + protected final int iterations; + private final BlobType btype; + + public UsageThresholdExceededTest(BlobType btype, int iterations) { + this.btype = btype; + this.iterations = iterations; + } + + public static void main(String[] args) { + int iterationsCount = + Integer.getInteger("com.oracle.java.testlibrary.iterations", 1); + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdExceededTest(btype, iterationsCount) + .runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long oldValue = bean.getUsageThresholdCount(); + for (int i = 0; i < iterations; i++) { + CodeCacheUtils.hitUsageThreshold(bean, btype); + } + Asserts.assertEQ(bean.getUsageThresholdCount(), oldValue + iterations, + "Unexpected threshold usage count"); + System.out.printf("INFO: Scenario finished successfully for %s%n", + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdIncreasedTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdIncreasedTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:CompileCommand=compileonly,null::* + * UsageThresholdIncreasedTest + * @summary verifying that threshold hasn't been hit after allocation smaller + * than threshold value and that threshold value can be changed + */ +public class UsageThresholdIncreasedTest { + + private static final int ALLOCATION_STEP = 5; + private static final long THRESHOLD_STEP = ALLOCATION_STEP + * CodeCacheUtils.MIN_ALLOCATION; + private final BlobType btype; + + public UsageThresholdIncreasedTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + new UsageThresholdIncreasedTest(btype).runTest(); + } + } + + private void checkUsageThresholdCount(MemoryPoolMXBean bean, long count){ + Asserts.assertEQ(bean.getUsageThresholdCount(), count, + String.format("Usage threshold was hit: %d times for %s " + + "Threshold value: %d with current usage: %d", + bean.getUsageThresholdCount(), bean.getName(), + bean.getUsageThreshold(), bean.getUsage().getUsed())); + } + + protected void runTest() { + long headerSize = CodeCacheUtils.getHeaderSize(btype); + long allocationUnit = CodeCacheUtils.MIN_ALLOCATION - headerSize; + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialCount = bean.getUsageThresholdCount(); + long initialSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + // Usage threshold check is triggered by GC cycle, so, call it + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + long filledSize = bean.getUsage().getUsed(); + bean.setUsageThreshold(filledSize + THRESHOLD_STEP); + for (int i = 0; i < ALLOCATION_STEP - 1; i++) { + CodeCacheUtils.WB.allocateCodeBlob(allocationUnit, btype.id); + } + CodeCacheUtils.WB.fullGC(); + checkUsageThresholdCount(bean, initialCount); + System.out.println("INFO: Case finished successfully for " + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import java.lang.management.MemoryPoolMXBean; +import sun.hotspot.code.BlobType; + +/* + * @test UsageThresholdNotExceededTest + * @library /testlibrary /../../test/lib + * @build UsageThresholdNotExceededTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:-UseCodeCacheFlushing + * -XX:-MethodFlushing -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+SegmentedCodeCache -XX:CompileCommand=compileonly,null::* + * UsageThresholdNotExceededTest + * @summary verifying that usage threshold not exceeded while allocating less + * than usage threshold + */ +public class UsageThresholdNotExceededTest { + + private final BlobType btype; + + public UsageThresholdNotExceededTest(BlobType btype) { + this.btype = btype; + } + + public static void main(String[] args) { + for (BlobType btype : BlobType.getAvailable()) { + if (CodeCacheUtils.isCodeHeapPredictable(btype)) { + new UsageThresholdNotExceededTest(btype).runTest(); + } + } + } + + protected void runTest() { + MemoryPoolMXBean bean = btype.getMemoryPool(); + long initialThresholdCount = bean.getUsageThresholdCount(); + long initialUsage = bean.getUsage().getUsed(); + bean.setUsageThreshold(initialUsage + 1 + CodeCacheUtils.MIN_ALLOCATION); + CodeCacheUtils.WB.allocateCodeBlob(CodeCacheUtils.MIN_ALLOCATION + - CodeCacheUtils.getHeaderSize(btype), btype.id); + // a gc cycle triggers usage threshold recalculation + CodeCacheUtils.WB.fullGC(); + Asserts.assertEQ(bean.getUsageThresholdCount(), initialThresholdCount, + String.format("Usage threshold was hit: %d times for %s. " + + "Threshold value: %d with current usage: %d", + bean.getUsageThresholdCount(), bean.getName(), + bean.getUsageThreshold(), bean.getUsage().getUsed())); + + System.out.println("INFO: Case finished successfully for " + + bean.getName()); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Tue Jan 20 10:22:44 2015 -0800 @@ -127,10 +127,7 @@ @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void lock(boolean abort) { @@ -148,10 +145,12 @@ public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.lock(i >= Test.WARMUP_ITERATIONS); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Tue Jan 20 10:22:44 2015 -0800 @@ -157,10 +157,7 @@ @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::forceAbort" - }; + return new String[] { getMethodWithLockName() }; } public void forceAbort(int a[], boolean abort) { @@ -183,13 +180,15 @@ public static void main(String args[]) throws Throwable { Test t = new Test(); - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } int tmp[] = new int[1]; for (int i = 0; i < Test.ITERATIONS; i++ ) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); if (i == Test.RANGE_CHECK_AT) { t.forceAbort(new int[0], false); } else { diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Tue Jan 20 10:22:44 2015 -0800 @@ -130,10 +130,7 @@ @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void forceAbort(boolean abort) { @@ -151,11 +148,12 @@ public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.forceAbort( i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD); } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Tue Jan 20 10:22:44 2015 -0800 @@ -143,10 +143,7 @@ @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName(), - sun.misc.Unsafe.class.getName() + "::addressSize" - }; + return new String[] { getMethodWithLockName() }; } public void lock(boolean abort) { @@ -164,11 +161,12 @@ public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test t = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(t.monitor); } for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated); t.lock(i % 2 == 1); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Tue Jan 20 10:22:44 2015 -0800 @@ -117,9 +117,7 @@ @Override public String[] getMethodsToCompileNames() { - return new String[] { - getMethodWithLockName() - }; + return new String[] { getMethodWithLockName() }; } public void lock() { @@ -135,11 +133,13 @@ public static void main(String args[]) throws Throwable { Asserts.assertGTE(args.length, 1, "One argument required."); Test test = new Test(); - - if (Boolean.valueOf(args[0])) { + boolean shouldBeInflated = Boolean.valueOf(args[0]); + if (shouldBeInflated) { AbortProvoker.inflateMonitor(test.monitor); } for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(test.monitor, + shouldBeInflated); test.lock(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Tue Jan 20 10:22:44 2015 -0800 @@ -52,7 +52,7 @@ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before * lock inflation and the same amount of times after inflation. * As a result total locks count should be equal to - * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}. + * {@code 2 * AbortProvoker.DEFAULT_ITERATIONS}. * It is a pretty strict assertion which could fail if some retriable abort * happened: it could be {@code AbortType.RETRIABLE} or * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these @@ -101,7 +101,6 @@ } public static class Test { - /** * Usage: * Test <provoker type> @@ -113,10 +112,12 @@ AbortProvoker provoker = AbortType.lookup(Integer.valueOf(args[0])).provoker(); for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(provoker, false /*deflated*/); provoker.forceAbort(); } provoker.inflateMonitor(); for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) { + AbortProvoker.verifyMonitorState(provoker, true /*inflated*/); provoker.forceAbort(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/testlibrary/CompilerUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import java.util.stream.IntStream; +import sun.hotspot.WhiteBox; + +public class CompilerUtils { + + private CompilerUtils() { + // to prevent from instantiation + } + + /** + * Returns available compilation levels + * + * @return int array with compilation levels + */ + public static int[] getAvailableCompilationLevels() { + if (!WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompiler")) { + return new int[0]; + } + if (WhiteBox.getWhiteBox().getBooleanVMFlag("TieredCompilation")) { + Long flagValue = WhiteBox.getWhiteBox() + .getIntxVMFlag("TieredStopAtLevel"); + int maxLevel = flagValue.intValue(); + Asserts.assertEQ(new Long(maxLevel), flagValue, + "TieredStopAtLevel has value out of int capacity"); + return IntStream.rangeClosed(1, maxLevel).toArray(); + } else { + if (Platform.isServer()) { + return new int[]{4}; + } + if (Platform.isClient() || Platform.isMinimal()) { + return new int[]{1}; + } + } + return new int[0]; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java --- a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Tue Jan 20 10:22:44 2015 -0800 @@ -29,8 +29,7 @@ import java.util.concurrent.CyclicBarrier; import com.oracle.java.testlibrary.Asserts; -import com.oracle.java.testlibrary.Utils; -import sun.misc.Unsafe; +import sun.hotspot.WhiteBox; /** * Base class for different transactional execution abortion @@ -38,6 +37,9 @@ */ public abstract class AbortProvoker implements CompilableTest { public static final long DEFAULT_ITERATIONS = 10000L; + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + @SuppressWarnings("unused") + private static int sharedState = 0; /** * Inflates monitor associated with object {@code monitor}. * Inflation is forced by entering the same monitor from @@ -48,36 +50,76 @@ * @throws Exception if something went wrong. */ public static Object inflateMonitor(Object monitor) throws Exception { - Unsafe unsafe = Utils.getUnsafe(); CyclicBarrier barrier = new CyclicBarrier(2); Runnable inflatingRunnable = () -> { - unsafe.monitorEnter(monitor); - try { - barrier.await(); - barrier.await(); - } catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException( - "Synchronization issue occurred.", e); - } finally { - unsafe.monitorExit(monitor); + synchronized (monitor) { + try { + barrier.await(); + } catch (BrokenBarrierException | InterruptedException e) { + throw new RuntimeException( + "Synchronization issue occurred.", e); + } + try { + monitor.wait(); + } catch (InterruptedException e) { + throw new AssertionError("The thread waiting on an" + + " inflated monitor was interrupted, thus test" + + " results may be incorrect.", e); + } } }; Thread t = new Thread(inflatingRunnable); + t.setDaemon(true); t.start(); // Wait until thread t enters the monitor. barrier.await(); - // At this point monitor will be owned by thread t, - // so our attempt to enter the same monitor will force - // monitor inflation. - Asserts.assertFalse(unsafe.tryMonitorEnter(monitor), - "Not supposed to enter the monitor first"); - barrier.await(); - t.join(); + synchronized (monitor) { + // At this point thread t is already waiting on the monitor. + // Modifying static field just to avoid lock's elimination. + sharedState++; + } + verifyMonitorState(monitor, true /* inflated */); return monitor; } + /** + * Verifies that {@code monitor} is a stack-lock or inflated lock depending + * on {@code shouldBeInflated} value. If {@code monitor} is inflated while + * it is expected that it should be a stack-lock, then this method attempts + * to deflate it by forcing a safepoint and then verifies the state once + * again. + * + * @param monitor monitor to be verified. + * @param shouldBeInflated flag indicating whether or not monitor is + * expected to be inflated. + * @throws RuntimeException if the {@code monitor} in a wrong state. + */ + public static void verifyMonitorState(Object monitor, + boolean shouldBeInflated) { + if (!shouldBeInflated && WHITE_BOX.isMonitorInflated(monitor)) { + WHITE_BOX.forceSafepoint(); + } + Asserts.assertEQ(WHITE_BOX.isMonitorInflated(monitor), shouldBeInflated, + "Monitor in a wrong state."); + } + /** + * Verifies that monitor used by the {@code provoker} is a stack-lock or + * inflated lock depending on {@code shouldBeInflated} value. If such + * monitor is inflated while it is expected that it should be a stack-lock, + * then this method attempts to deflate it by forcing a safepoint and then + * verifies the state once again. + * + * @param provoker AbortProvoker whose monitor's state should be verified. + * @param shouldBeInflated flag indicating whether or not monitor is + * expected to be inflated. + * @throws RuntimeException if the {@code monitor} in a wrong state. + */ + public static void verifyMonitorState(AbortProvoker provoker, + boolean shouldBeInflated) { + verifyMonitorState(provoker.monitor, shouldBeInflated); + } /** * Get instance of specified AbortProvoker, inflate associated monitor @@ -120,6 +162,7 @@ } for (long i = 0; i < iterations; i++) { + AbortProvoker.verifyMonitorState(provoker, monitorShouldBeInflated); provoker.forceAbort(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/testlibrary/rtm/BusyLock.java --- a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Tue Jan 20 10:22:44 2015 -0800 @@ -77,7 +77,7 @@ } } - public void test() { + public void syncAndTest() { try { barrier.await(); // wait until monitor is locked by a ::run method @@ -85,6 +85,10 @@ } catch (InterruptedException | BrokenBarrierException e) { throw new RuntimeException("Synchronization error happened.", e); } + test(); + } + + public void test() { synchronized(monitor) { BusyLock.field++; } @@ -130,7 +134,7 @@ Thread t = new Thread(busyLock); t.start(); - busyLock.test(); + busyLock.syncAndTest(); t.join(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java --- a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Tue Jan 20 10:22:44 2015 -0800 @@ -69,11 +69,6 @@ * Accesses and modifies memory region from within the transaction. */ public void transactionalRegion() { - try { - barrier.await(); - } catch (InterruptedException | BrokenBarrierException e) { - throw new RuntimeException(e); - } for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) { synchronized(monitor) { MemoryConflictProvoker.field--; @@ -86,6 +81,11 @@ try { Thread t = new Thread(conflictingThread); t.start(); + try { + barrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } transactionalRegion(); t.join(); } catch (Exception e) { diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java --- a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Tue Jan 20 10:22:44 2015 -0800 @@ -240,7 +240,8 @@ Collections.addAll(finalVMOpts, "-Xcomp", "-server", "-XX:-TieredCompilation", "-XX:+UseRTMLocking", CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, - CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI"); if (test != null) { for (String method : test.getMethodsToCompileNames()) { diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test TestEagerReclaimHumongousRegions2 - * @bug 8051973 - * @summary Test to make sure that eager reclaim of humongous objects correctly clears - * mark bitmaps at reclaim. - * @key gc - * @library /testlibrary - */ - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Random; - -import com.oracle.java.testlibrary.OutputAnalyzer; -import com.oracle.java.testlibrary.ProcessTools; - -// An object that has a few references to other instances to slow down marking. -class ObjectWithSomeRefs { - public ObjectWithSomeRefs other1; - public ObjectWithSomeRefs other2; - public ObjectWithSomeRefs other3; - public ObjectWithSomeRefs other4; -} - -class ReclaimRegionFast { - public static final long MAX_MILLIS_FOR_RUN = 50 * 1000; // The maximum runtime for the actual test. - - public static final int M = 1024*1024; - - public static LinkedList garbageList = new LinkedList(); - - public static void genGarbage(Object large) { - for (int i = 0; i < 64*1024; i++) { - Object[] garbage = new Object[50]; - garbage[0] = large; - garbageList.add(garbage); - } - garbageList.clear(); - } - - public static ArrayList longList = new ArrayList(); - - public static void main(String[] args) { - - for (int i = 0; i < 16*1024; i++) { - longList.add(new ObjectWithSomeRefs()); - } - - Random rnd = new Random(); - for (int i = 0; i < longList.size(); i++) { - int len = longList.size(); - longList.get(i).other1 = longList.get(rnd.nextInt(len)); - longList.get(i).other2 = longList.get(rnd.nextInt(len)); - longList.get(i).other3 = longList.get(rnd.nextInt(len)); - longList.get(i).other4 = longList.get(rnd.nextInt(len)); - } - - int[] large1 = new int[M]; - int[] large2 = null; - int[] large3 = null; - int[] large4 = null; - - Object ref_from_stack = large1; - - long start_millis = System.currentTimeMillis(); - - for (int i = 0; i < 20; i++) { - long current_millis = System.currentTimeMillis(); - if ((current_millis - start_millis) > MAX_MILLIS_FOR_RUN) { - System.out.println("Finishing test because maximum runtime exceeded"); - break; - } - // A set of large objects that will be reclaimed eagerly - and hopefully marked. - large1 = new int[M - 20]; - large2 = new int[M - 20]; - large3 = new int[M - 20]; - large4 = new int[M - 20]; - genGarbage(large1); - // Make sure that the compiler cannot completely remove - // the allocation of the large object until here. - System.out.println(large1 + " " + large2 + " " + large3 + " " + large4); - } - - // Keep the reference to the first object alive. - System.out.println(ref_from_stack); - } -} - -public class TestEagerReclaimHumongousRegions2 { - public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseG1GC", - "-Xms128M", - "-Xmx128M", - "-Xmn2M", - "-XX:G1HeapRegionSize=1M", - "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible initial marks. - "-XX:+PrintGC", - "-XX:+VerifyAfterGC", - "-XX:ConcGCThreads=1", // Want to make marking as slow as possible. - "-XX:+IgnoreUnrecognizedVMOptions", // G1VerifyBitmaps is develop only. - "-XX:+G1VerifyBitmaps", - ReclaimRegionFast.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); - } -} - diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestEagerReclaimHumongousRegionsClearMarkBits + * @bug 8051973 + * @summary Test to make sure that eager reclaim of humongous objects correctly clears + * mark bitmaps at reclaim. + * @key gc + * @library /testlibrary + */ + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Random; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +// An object that has a few references to other instances to slow down marking. +class ObjectWithSomeRefs { + public ObjectWithSomeRefs other1; + public ObjectWithSomeRefs other2; + public ObjectWithSomeRefs other3; + public ObjectWithSomeRefs other4; +} + +class ReclaimRegionFast { + public static final long MAX_MILLIS_FOR_RUN = 50 * 1000; // The maximum runtime for the actual test. + + public static final int M = 1024*1024; + + public static LinkedList garbageList = new LinkedList(); + + public static void genGarbage(Object large) { + for (int i = 0; i < 64*1024; i++) { + Object[] garbage = new Object[50]; + garbage[0] = large; + garbageList.add(garbage); + } + garbageList.clear(); + } + + public static ArrayList longList = new ArrayList(); + + public static void main(String[] args) { + + for (int i = 0; i < 16*1024; i++) { + longList.add(new ObjectWithSomeRefs()); + } + + Random rnd = new Random(); + for (int i = 0; i < longList.size(); i++) { + int len = longList.size(); + longList.get(i).other1 = longList.get(rnd.nextInt(len)); + longList.get(i).other2 = longList.get(rnd.nextInt(len)); + longList.get(i).other3 = longList.get(rnd.nextInt(len)); + longList.get(i).other4 = longList.get(rnd.nextInt(len)); + } + + int[] large1 = new int[M]; + int[] large2 = null; + int[] large3 = null; + int[] large4 = null; + + Object ref_from_stack = large1; + + long start_millis = System.currentTimeMillis(); + + for (int i = 0; i < 20; i++) { + long current_millis = System.currentTimeMillis(); + if ((current_millis - start_millis) > MAX_MILLIS_FOR_RUN) { + System.out.println("Finishing test because maximum runtime exceeded"); + break; + } + // A set of large objects that will be reclaimed eagerly - and hopefully marked. + large1 = new int[M - 20]; + large2 = new int[M - 20]; + large3 = new int[M - 20]; + large4 = new int[M - 20]; + genGarbage(large1); + // Make sure that the compiler cannot completely remove + // the allocation of the large object until here. + System.out.println(large1 + " " + large2 + " " + large3 + " " + large4); + } + + // Keep the reference to the first object alive. + System.out.println(ref_from_stack); + } +} + +public class TestEagerReclaimHumongousRegionsClearMarkBits { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn2M", + "-XX:G1HeapRegionSize=1M", + "-XX:InitiatingHeapOccupancyPercent=0", // Want to have as much as possible initial marks. + "-XX:+PrintGC", + "-XX:+VerifyAfterGC", + "-XX:ConcGCThreads=1", // Want to make marking as slow as possible. + "-XX:+IgnoreUnrecognizedVMOptions", // G1VerifyBitmaps is develop only. + "-XX:+G1VerifyBitmaps", + ReclaimRegionFast.class.getName()); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } +} + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestEagerReclaimHumongousRegionsWithRefs + * @bug 8048179 + * @summary Test to make sure that eager reclaim of humongous objects that have previously + * been referenced by other old gen regions work. We simply try to fill + * up the heap with humongous objects and create a remembered set entry from an object by + * referencing that we know is in the old gen. After changing this reference, the object + * should still be eagerly reclaimable to avoid Full GC. + * @key gc + * @library /testlibrary + */ + +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.LinkedList; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import static com.oracle.java.testlibrary.Asserts.*; + +class RefHolder { + Object ref; +} + +class ReclaimRegionFast { + + public static final int M = 1024*1024; + + public static LinkedList garbageList = new LinkedList(); + + public static void genGarbage() { + for (int i = 0; i < 32*1024; i++) { + garbageList.add(new int[100]); + } + garbageList.clear(); + } + + + // A large object referenced by a static. + static int[] filler = new int[10 * M]; + + // Old gen object referencing the large object, generating remembered + // set entries. + static RefHolder fromOld = new RefHolder(); + + public static void main(String[] args) { + + int[] large = new int[M]; + + Object ref_from_stack = large; + + for (int i = 0; i < 100; i++) { + // A large object that will be reclaimed eagerly. + large = new int[6*M]; + fromOld.ref = large; + genGarbage(); + } + + // Keep the reference to the first object alive. + System.out.println(ref_from_stack); + } +} + +public class TestEagerReclaimHumongousRegionsWithRefs { + + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn16M", + "-XX:+PrintGC", + ReclaimRegionFast.class.getName()); + + Pattern p = Pattern.compile("Full GC"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + int found = 0; + Matcher m = p.matcher(output.getStdout()); + while (m.find()) { + found++; + } + System.out.println("Issued " + found + " Full GCs"); + + assertLessThan(found, 10, "Found that " + found + " Full GCs were issued. This is larger than the bound. Eager reclaim of objects once referenced from old gen seems to not work at all"); + output.shouldHaveExitValue(0); + } +} + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestG1TraceEagerReclaimHumongousObjects + * @bug 8058801 8048179 + * @summary Ensure that the output for a G1TraceEagerReclaimHumongousObjects + * includes the expected necessary messages. + * @key gc + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; +import java.util.LinkedList; + +public class TestG1TraceEagerReclaimHumongousObjects { + public static void main(String[] args) throws Exception { + testGCLogs(); + testHumongousObjectGCLogs(); + } + + private static void testGCLogs() throws Exception { + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn16M", + "-XX:G1HeapRegionSize=1M", + "-XX:+PrintGC", + "-XX:+UnlockExperimentalVMOptions", + "-XX:G1LogLevel=finest", + "-XX:+G1TraceEagerReclaimHumongousObjects", + GCTest.class.getName()); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + // As G1EagerReclaimHumongousObjects is set(default), below logs should be displayed. + // And GCTest doesn't have humongous objects, so values should be zero. + output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Total: 0]"); + output.shouldContain("[Humongous Candidate: 0]"); + output.shouldContain("[Humongous Reclaimed: 0]"); + + output.shouldHaveExitValue(0); + } + + private static void testHumongousObjectGCLogs() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", + "-Xms128M", + "-Xmx128M", + "-Xmn16M", + "-XX:G1HeapRegionSize=1M", + "-XX:+PrintGC", + "-XX:+UnlockExperimentalVMOptions", + "-XX:G1LogLevel=finest", + "-XX:+G1TraceEagerReclaimHumongousObjects", + GCWithHumongousObjectTest.class.getName()); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed. + output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Total"); + output.shouldContain("[Humongous Candidate"); + output.shouldContain("[Humongous Reclaimed"); + + // As G1TraceReclaimDeadHumongousObjectsAtYoungGC is set and GCWithHumongousObjectTest has humongous objects, + // these logs should be displayed. + output.shouldContain("Live humongous"); + output.shouldContain("Dead humongous region"); + output.shouldHaveExitValue(0); + } + + static class GCTest { + private static byte[] garbage; + + public static void main(String [] args) { + System.out.println("Creating garbage"); + // create 128MB of garbage. This should result in at least one GC + for (int i = 0; i < 1024; i++) { + garbage = new byte[128 * 1024]; + } + System.out.println("Done"); + } + } + + static class GCWithHumongousObjectTest { + + public static final int M = 1024*1024; + public static LinkedList garbageList = new LinkedList(); + // A large object referenced by a static. + static int[] filler = new int[10 * M]; + + public static void genGarbage() { + for (int i = 0; i < 32*1024; i++) { + garbageList.add(new int[100]); + } + garbageList.clear(); + } + + public static void main(String[] args) { + + int[] large = new int[M]; + Object ref = large; + + System.out.println("Creating garbage"); + for (int i = 0; i < 100; i++) { + // A large object that will be reclaimed eagerly. + large = new int[6*M]; + genGarbage(); + // Make sure that the compiler cannot completely remove + // the allocation of the large object until here. + System.out.println(large); + } + + // Keep the reference to the first object alive. + System.out.println(ref); + System.out.println("Done"); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java --- a/hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test TestG1TraceReclaimDeadHumongousObjectsAtYoungGC - * @bug 8058801 - * @summary Ensure that the output for a G1TraceReclaimDeadHumongousObjectsAtYoungGC - * includes the expected necessary messages. - * @key gc - * @library /testlibrary - */ - -import com.oracle.java.testlibrary.ProcessTools; -import com.oracle.java.testlibrary.OutputAnalyzer; -import java.util.LinkedList; - -public class TestG1TraceReclaimDeadHumongousObjectsAtYoungGC { - public static void main(String[] args) throws Exception { - testGCLogs(); - testHumongousObjectGCLogs(); - } - - private static void testGCLogs() throws Exception { - - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", - "-Xms128M", - "-Xmx128M", - "-Xmn16M", - "-XX:G1HeapRegionSize=1M", - "-XX:+PrintGC", - "-XX:+UnlockExperimentalVMOptions", - "-XX:G1LogLevel=finest", - "-XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC", - GCTest.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - - // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed. - // And GCTest doesn't have humongous objects, so values should be zero. - output.shouldContain("[Humongous Reclaim"); - output.shouldContain("[Humongous Total: 0]"); - output.shouldContain("[Humongous Candidate: 0]"); - output.shouldContain("[Humongous Reclaimed: 0]"); - - output.shouldHaveExitValue(0); - } - - private static void testHumongousObjectGCLogs() throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", - "-Xms128M", - "-Xmx128M", - "-Xmn16M", - "-XX:G1HeapRegionSize=1M", - "-XX:+PrintGC", - "-XX:+UnlockExperimentalVMOptions", - "-XX:G1LogLevel=finest", - "-XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC", - GCWithHumongousObjectTest.class.getName()); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - - // As G1ReclaimDeadHumongousObjectsAtYoungGC is set(default), below logs should be displayed. - output.shouldContain("[Humongous Reclaim"); - output.shouldContain("[Humongous Total"); - output.shouldContain("[Humongous Candidate"); - output.shouldContain("[Humongous Reclaimed"); - - // As G1TraceReclaimDeadHumongousObjectsAtYoungGC is set and GCWithHumongousObjectTest has humongous objects, - // these logs should be displayed. - output.shouldContain("Live humongous"); - output.shouldContain("Reclaim humongous region"); - output.shouldHaveExitValue(0); - } - - static class GCTest { - private static byte[] garbage; - - public static void main(String [] args) { - System.out.println("Creating garbage"); - // create 128MB of garbage. This should result in at least one GC - for (int i = 0; i < 1024; i++) { - garbage = new byte[128 * 1024]; - } - System.out.println("Done"); - } - } - - static class GCWithHumongousObjectTest { - - public static final int M = 1024*1024; - public static LinkedList garbageList = new LinkedList(); - // A large object referenced by a static. - static int[] filler = new int[10 * M]; - - public static void genGarbage() { - for (int i = 0; i < 32*1024; i++) { - garbageList.add(new int[100]); - } - garbageList.clear(); - } - - public static void main(String[] args) { - - int[] large = new int[M]; - Object ref = large; - - System.out.println("Creating garbage"); - for (int i = 0; i < 100; i++) { - // A large object that will be reclaimed eagerly. - large = new int[6*M]; - genGarbage(); - // Make sure that the compiler cannot completely remove - // the allocation of the large object until here. - System.out.println(large); - } - - // Keep the reference to the first object alive. - System.out.println(ref); - System.out.println("Done"); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/gc/g1/TestGCLogMessages.java --- a/hotspot/test/gc/g1/TestGCLogMessages.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/gc/g1/TestGCLogMessages.java Tue Jan 20 10:22:44 2015 -0800 @@ -23,7 +23,7 @@ /* * @test TestGCLogMessages - * @bug 8035406 8027295 8035398 8019342 8027959 + * @bug 8035406 8027295 8035398 8019342 8027959 8048179 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. * @key gc @@ -54,6 +54,7 @@ output.shouldNotContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); output.shouldNotContain("[Non-Young Free CSet"); + output.shouldNotContain("[Humongous Register"); output.shouldNotContain("[Humongous Reclaim"); output.shouldHaveExitValue(0); @@ -72,9 +73,10 @@ output.shouldContain("[String Dedup Fixup"); output.shouldNotContain("[Young Free CSet"); output.shouldNotContain("[Non-Young Free CSet"); - output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Register"); output.shouldNotContain("[Humongous Total"); output.shouldNotContain("[Humongous Candidate"); + output.shouldContain("[Humongous Reclaim"); output.shouldNotContain("[Humongous Reclaimed"); output.shouldHaveExitValue(0); @@ -95,9 +97,10 @@ output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); output.shouldContain("[Non-Young Free CSet"); - output.shouldContain("[Humongous Reclaim"); + output.shouldContain("[Humongous Register"); output.shouldContain("[Humongous Total"); output.shouldContain("[Humongous Candidate"); + output.shouldContain("[Humongous Reclaim"); output.shouldContain("[Humongous Reclaimed"); output.shouldHaveExitValue(0); } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6583051 + * @summary Give error if java.lang.Object has been incompatibly overridden on the bootpath + * @library /testlibrary + * @compile Object.java + * @run main BootstrapRedefine + */ + +import com.oracle.java.testlibrary.*; + +public class BootstrapRedefine { + + public static void main(String[] args) throws Exception { + String testClasses = System.getProperty("test.classes", "."); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/p:" + testClasses, "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Incompatible definition of java.lang.Object") + .shouldHaveExitValue(1); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/BadObjectClass/Object.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/BadObjectClass/Object.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang; + +/** + * This is a fake java.lang.Object class. + */ +public class Object { + + // Add some methods + void dummy1() { return; } + void dummy2() { return; } + void dummy3() { return; } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test TestNullTerminatedFlags + * @bug 6522873 + * @summary Test that the VM don't allow random junk characters at the end of valid command line flags. + * @library /testlibrary + * @run driver TestNullTerminatedFlags + */ +public class TestNullTerminatedFlags { + public static String[] options = { + "-Xnoclassgc", + "-Xconcgc", + "-Xnoconcgc", + "-Xbatch", + "-green", + "-native", + "-Xsqnopause", + "-Xrs", + "-Xusealtsigs", + "-Xoptimize", + "-Xprof", + "-Xconcurrentio", + "-Xinternalversion", + "-Xprintflags", + "-Xint", + "-Xmixed", + "-Xcomp", + "-Xshare:dump", + "-Xshare:on", + "-Xshare:auto", + "-Xshare:off", + "-Xdebug", + "-Xnoagent", + "-Xboundthreads" + }; + + public static void main(String args[]) throws Exception{ + for (String option : options) { + String testOption = option + "junk"; + ProcessBuilder pb = + ProcessTools.createJavaProcessBuilder(testOption, "-version"); + new OutputAnalyzer(pb.start()) + .shouldContain("Unrecognized option: " + testOption) + .shouldHaveExitValue(1); + } + } +} + diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/CompressedOops/UseCompressedOops.java --- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Tue Jan 20 10:22:44 2015 -0800 @@ -35,20 +35,42 @@ public class UseCompressedOops { public static void main(String[] args) throws Exception { + testCompressedOopsModesGCs(); + testCompressedOopsModesGCs("-XX:+UseLargePages"); + } + + public static void testCompressedOopsModesGCs(String... flags) throws Exception { + ArrayList args = new ArrayList<>(); + Collections.addAll(args, flags); + + // Test default. + testCompressedOopsModes(args); + // Test GCs. + testCompressedOopsModes(args, "-XX:+UseG1GC"); + testCompressedOopsModes(args, "-XX:+UseConcMarkSweepGC"); + testCompressedOopsModes(args, "-XX:+UseSerialGC"); + testCompressedOopsModes(args, "-XX:+UseParallelGC"); + testCompressedOopsModes(args, "-XX:+UseParallelOldGC"); + } + + public static void testCompressedOopsModes(ArrayList flags1, String... flags2) throws Exception { + ArrayList args = new ArrayList<>(); + args.addAll(flags1); + Collections.addAll(args, flags2); if (Platform.is64bit()) { // Explicitly turn of compressed oops - testCompressedOops("-XX:-UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:-UseCompressedOops", "-Xmx32m") .shouldNotContain("Compressed Oops") .shouldHaveExitValue(0); // Compressed oops should be on by default - testCompressedOops("-Xmx32m") + testCompressedOops(args, "-Xmx32m") .shouldContain("Compressed Oops mode") .shouldHaveExitValue(0); // Explicly enabling compressed oops - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") .shouldContain("Compressed Oops mode") .shouldHaveExitValue(0); @@ -58,68 +80,89 @@ // puts the heap way up, forcing different behaviour. if (!Platform.isOSX() && !Platform.isSolaris()) { // Larger than 4gb heap should result in zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx5g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx5g") + .shouldContain("Zero based") + .shouldContain("Oop shift amount: 3") + .shouldHaveExitValue(0); + + // Larger than 3gb heap and HeapBaseMinAddress=1g should result in zero based with shift 3 + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx3200m", "-XX:HeapBaseMinAddress=1g") .shouldContain("Zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // Small heap above 4gb should result in zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=4g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=4g") .shouldContain("Zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // Small heap above 32gb should result in non-zero based with shift 3 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=32g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=32g") + .shouldContain("Non-zero disjoint base") + .shouldContain("Oop shift amount: 3") + .shouldHaveExitValue(0); + + // Small heap above 32gb should result in non-zero based with shift 3 + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m", "-XX:HeapBaseMinAddress=72704m") .shouldContain("Non-zero based") .shouldContain("Oop shift amount: 3") .shouldHaveExitValue(0); // 32gb heap with heap base above 64gb and object alignment set to 16 bytes should result // in non-zero based with shift 4 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16", + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16", "-XX:HeapBaseMinAddress=64g") - .shouldContain("Non-zero based") + .shouldContain("Non-zero disjoint base") .shouldContain("Oop shift amount: 4") .shouldHaveExitValue(0); // 32gb heap with object alignment set to 16 bytes should result in zero based with shift 4 - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=16") .shouldContain("Zero based") .shouldContain("Oop shift amount: 4") .shouldHaveExitValue(0); } + // This is a pathologic case for the heap allocation algorithm. Regression test. + // HeapBaseMinAddress must be 2g and should not be set on the command line. + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx2g") + .shouldNotContain("Max heap size too large for Compressed Oops") + .shouldHaveExitValue(0); + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx29g", "-XX:CompressedClassSpaceSize=1g") + .shouldNotContain("Max heap size too large for Compressed Oops") + .shouldHaveExitValue(0); + // Explicitly enabling compressed oops with 32gb heap should result a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // 32gb heap should not result a warning - testCompressedOops("-Xmx32g") + testCompressedOops(args, "-Xmx32g") .shouldNotContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // Explicitly enabling compressed oops with 32gb heap and object // alignment set to 8 byte should result a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=8") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32g", "-XX:ObjectAlignmentInBytes=8") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); // 64gb heap and object alignment set to 16 bytes should result in a warning - testCompressedOops("-XX:+UseCompressedOops", "-Xmx64g", "-XX:ObjectAlignmentInBytes=16") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx64g", "-XX:ObjectAlignmentInBytes=16") .shouldContain("Max heap size too large for Compressed Oops") .shouldHaveExitValue(0); } else { // Compressed oops should only apply to 64bit platforms - testCompressedOops("-XX:+UseCompressedOops", "-Xmx32m") + testCompressedOops(args, "-XX:+UseCompressedOops", "-Xmx32m") .shouldContain("Unrecognized VM option 'UseCompressedOops'") .shouldHaveExitValue(1); } } - private static OutputAnalyzer testCompressedOops(String... flags) throws Exception { + private static OutputAnalyzer testCompressedOops(ArrayList flags1, String... flags2) throws Exception { ArrayList args = new ArrayList<>(); // Always run with these three: @@ -128,7 +171,8 @@ args.add("-Xms32m"); // Add the extra flags - Collections.addAll(args, flags); + args.addAll(flags1); + Collections.addAll(args, flags2); args.add("-version"); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8059510 + * @summary Test jcmd VM.symboltable and VM.stringtable options + * @library /testlibrary + * @run main/othervm -XX:+UnlockDiagnosticVMOptions DumpSymbolAndStringTable + */ + +import com.oracle.java.testlibrary.*; + +public class DumpSymbolAndStringTable { + public static void main(String[] args) throws Exception { + // Grab my own PID + String pid = Integer.toString(ProcessTools.getProcessId()); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.symboltable", "-verbose"}); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("24 2: DumpSymbolAndStringTable\n"); + } catch (RuntimeException e) { + output.shouldContain("Unknown diagnostic command"); + } + + pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.stringtable", "-verbose"}); + output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("16: java.lang.String\n"); + } catch (RuntimeException e) { + output.shouldContain("Unknown diagnostic command"); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8059510 + * @summary Test SharedSymbolTableBucketSize option + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class SharedSymbolTableBucketSize { + public static void main(String[] args) throws Exception { + int bucket_size = 8; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xshare:dump", "-XX:+PrintSharedSpaces", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", + "-XX:SharedSymbolTableBucketSize=" + Integer.valueOf(bucket_size)); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + + String s = output.firstMatch("Average bucket size : .*"); + Float f = Float.parseFloat(s.substring(25)); + int size = Math.round(f); + if (size != bucket_size) { + throw new Exception("FAILED: incorrect bucket size " + size + + ", expect " + bucket_size); + } + + + // Invalid SharedSymbolTableBucketSize input + String input[] = {"-XX:SharedSymbolTableBucketSize=-1", + "-XX:SharedSymbolTableBucketSize=2.5"}; + for (int i = 0; i < input.length; i++) { + pb = ProcessTools.createJavaProcessBuilder( + "-Xshare:dump", "-XX:+PrintSharedSpaces", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", + input[i]); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Improperly specified VM option"); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/stress/gc/TestGCOld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/stress/gc/TestGCOld.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* + * @test TestGCOld + * @key gc + * @key stress + * @requires vm.gc=="null" + * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects. + * @run main/othervm -Xmx384M -XX:+UseSerialGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseParallelGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseParallelGC -XX:-UseParallelOldGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseConcMarkSweepGC TestGCOld 50 1 20 10 10000 + * @run main/othervm -Xmx384M -XX:+UseG1GC TestGCOld 50 1 20 10 10000 + */ + +import java.text.*; +import java.util.Random; + +class TreeNode { + public TreeNode left, right; + public int val; // will always be the height of the tree +} + + +/* Args: + live-data-size: in megabytes (approximate, will be rounded down). + work: units of mutator non-allocation work per byte allocated, + (in unspecified units. This will affect the promotion rate + printed at the end of the run: more mutator work per step implies + fewer steps per second implies fewer bytes promoted per second.) + short/long ratio: ratio of short-lived bytes allocated to long-lived + bytes allocated. + pointer mutation rate: number of pointer mutations per step. + steps: number of steps to do. +*/ + +public class TestGCOld { + + // Command-line parameters. + + private static int size, workUnits, promoteRate, ptrMutRate, steps; + + // Constants. + + private static final int MEG = 1000000; + private static final int INSIGNIFICANT = 999; // this many bytes don't matter + private static final int BYTES_PER_WORD = 4; + private static final int BYTES_PER_NODE = 20; // bytes per TreeNode + private static final int WORDS_DEAD = 100; // size of young garbage object + + private final static int treeHeight = 14; + private final static long treeSize = heightToBytes(treeHeight); + + private static final String msg1 + = "Usage: java TestGCOld "; + private static final String msg2 + = " where is the live storage in megabytes"; + private static final String msg3 + = " is the mutator work per step (arbitrary units)"; + private static final String msg4 + = " is the ratio of short-lived to long-lived allocation"; + private static final String msg5 + = " is the mutations per step"; + private static final String msg6 + = " is the number of steps"; + + // Counters (and global variables that discourage optimization) + + private static long youngBytes = 0; // total young bytes allocated + private static long nodes = 0; // total tree nodes allocated + private static long actuallyMut = 0; // pointer mutations in old trees + private static long mutatorSum = 0; // checksum to discourage optimization + public static int[] aexport; // exported array to discourage opt + + // Global variables. + + private static TreeNode[] trees; + private static int where = 0; // roving index into trees + private static Random rnd = new Random(); + + // Returns the height of the given tree. + + private static int height (TreeNode t) { + if (t == null) { + return 0; + } + else { + return 1 + Math.max (height (t.left), height (t.right)); + } + } + + // Returns the length of the shortest path in the given tree. + + private static int shortestPath (TreeNode t) { + if (t == null) { + return 0; + } + else { + return 1 + Math.min (shortestPath (t.left), shortestPath (t.right)); + } + } + + // Returns the number of nodes in a balanced tree of the given height. + + private static long heightToNodes (int h) { + if (h == 0) { + return 0; + } + else { + long n = 1; + while (h > 1) { + n = n + n; + h = h - 1; + } + return n + n - 1; + } + } + + // Returns the number of bytes in a balanced tree of the given height. + + private static long heightToBytes (int h) { + return BYTES_PER_NODE * heightToNodes (h); + } + + // Returns the height of the largest balanced tree + // that has no more than the given number of nodes. + + private static int nodesToHeight (long nodes) { + int h = 1; + long n = 1; + while (n + n - 1 <= nodes) { + n = n + n; + h = h + 1; + } + return h - 1; + } + + // Returns the height of the largest balanced tree + // that occupies no more than the given number of bytes. + + private static int bytesToHeight (long bytes) { + return nodesToHeight (bytes / BYTES_PER_NODE); + } + + // Returns a newly allocated balanced binary tree of height h. + + private static TreeNode makeTree(int h) { + if (h == 0) return null; + else { + TreeNode res = new TreeNode(); + nodes++; + res.left = makeTree(h-1); + res.right = makeTree(h-1); + res.val = h; + return res; + } + } + + // Allocates approximately size megabytes of trees and stores + // them into a global array. + + private static void init() { + int ntrees = (int) ((size * MEG) / treeSize); + trees = new TreeNode[ntrees]; + + System.err.println("Allocating " + ntrees + " trees."); + System.err.println(" (" + (ntrees * treeSize) + " bytes)"); + for (int i = 0; i < ntrees; i++) { + trees[i] = makeTree(treeHeight); + // doYoungGenAlloc(promoteRate*ntrees*treeSize, WORDS_DEAD); + } + System.err.println(" (" + nodes + " nodes)"); + + /* Allow any in-progress GC to catch up... */ + // try { Thread.sleep(20000); } catch (InterruptedException x) {} + } + + // Confirms that all trees are balanced and have the correct height. + + private static void checkTrees() { + int ntrees = trees.length; + for (int i = 0; i < ntrees; i++) { + TreeNode t = trees[i]; + int h1 = height(t); + int h2 = shortestPath(t); + if ((h1 != treeHeight) || (h2 != treeHeight)) { + System.err.println("*****BUG: " + h1 + " " + h2); + } + } + } + + // Called only by replaceTree (below) and by itself. + + private static void replaceTreeWork(TreeNode full, TreeNode partial, boolean dir) { + boolean canGoLeft = full.left != null && full.left.val > partial.val; + boolean canGoRight = full.right != null && full.right.val > partial.val; + if (canGoLeft && canGoRight) { + if (dir) + replaceTreeWork(full.left, partial, !dir); + else + replaceTreeWork(full.right, partial, !dir); + } else if (!canGoLeft && !canGoRight) { + if (dir) + full.left = partial; + else + full.right = partial; + } else if (!canGoLeft) { + full.left = partial; + } else { + full.right = partial; + } + } + + // Given a balanced tree full and a smaller balanced tree partial, + // replaces an appropriate subtree of full by partial, taking care + // to preserve the shape of the full tree. + + private static void replaceTree(TreeNode full, TreeNode partial) { + boolean dir = (partial.val % 2) == 0; + actuallyMut++; + replaceTreeWork(full, partial, dir); + } + + // Allocates approximately n bytes of long-lived storage, + // replacing oldest existing long-lived storage. + + private static void oldGenAlloc(long n) { + int full = (int) (n / treeSize); + long partial = n % treeSize; + // System.out.println("In oldGenAlloc, doing " + full + " full trees " + // + "and one partial tree of size " + partial); + for (int i = 0; i < full; i++) { + trees[where++] = makeTree(treeHeight); + if (where == trees.length) where = 0; + } + while (partial > INSIGNIFICANT) { + int h = bytesToHeight(partial); + TreeNode newTree = makeTree(h); + replaceTree(trees[where++], newTree); + if (where == trees.length) where = 0; + partial = partial - heightToBytes(h); + } + } + + // Interchanges two randomly selected subtrees (of same size and depth). + + private static void oldGenSwapSubtrees() { + // Randomly pick: + // * two tree indices + // * A depth + // * A path to that depth. + int index1 = rnd.nextInt(trees.length); + int index2 = rnd.nextInt(trees.length); + int depth = rnd.nextInt(treeHeight); + int path = rnd.nextInt(); + TreeNode tn1 = trees[index1]; + TreeNode tn2 = trees[index2]; + for (int i = 0; i < depth; i++) { + if ((path & 1) == 0) { + tn1 = tn1.left; + tn2 = tn2.left; + } else { + tn1 = tn1.right; + tn2 = tn2.right; + } + path >>= 1; + } + TreeNode tmp; + if ((path & 1) == 0) { + tmp = tn1.left; + tn1.left = tn2.left; + tn2.left = tmp; + } else { + tmp = tn1.right; + tn1.right = tn2.right; + tn2.right = tmp; + } + actuallyMut += 2; + } + + // Update "n" old-generation pointers. + + private static void oldGenMut(long n) { + for (int i = 0; i < n/2; i++) { + oldGenSwapSubtrees(); + } + } + + // Does the amount of mutator work appropriate for n bytes of young-gen + // garbage allocation. + + private static void doMutWork(long n) { + int sum = 0; + long limit = workUnits*n/10; + for (long k = 0; k < limit; k++) sum++; + // We don't want dead code elimination to eliminate the loop above. + mutatorSum = mutatorSum + sum; + } + + // Allocate n bytes of young-gen garbage, in units of "nwords" + // words. + + private static void doYoungGenAlloc(long n, int nwords) { + final int nbytes = nwords*BYTES_PER_WORD; + int allocated = 0; + while (allocated < n) { + aexport = new int[nwords]; + /* System.err.println("Step"); */ + allocated += nbytes; + } + youngBytes = youngBytes + allocated; + } + + // Allocate "n" bytes of young-gen data; and do the + // corresponding amount of old-gen allocation and pointer + // mutation. + + // oldGenAlloc may perform some mutations, so this code + // takes those mutations into account. + + private static void doStep(long n) { + long mutations = actuallyMut; + + doYoungGenAlloc(n, WORDS_DEAD); + doMutWork(n); + oldGenAlloc(n / promoteRate); + oldGenMut(Math.max(0L, (mutations + ptrMutRate) - actuallyMut)); + } + + public static void main(String[] args) { + if (args.length != 5) { + System.err.println(msg1); + System.err.println(msg2); + System.err.println(msg3); + System.err.println(msg4); + System.err.println(msg5); + System.err.println(msg6); + return; + } + + size = Integer.parseInt(args[0]); + workUnits = Integer.parseInt(args[1]); + promoteRate = Integer.parseInt(args[2]); + ptrMutRate = Integer.parseInt(args[3]); + steps = Integer.parseInt(args[4]); + + System.out.println(size + " megabytes of live storage"); + System.out.println(workUnits + " work units per step"); + System.out.println("promotion ratio is 1:" + promoteRate); + System.out.println("pointer mutation rate is " + ptrMutRate); + System.out.println(steps + " steps"); + + init(); +// checkTrees(); + youngBytes = 0; + nodes = 0; + + System.err.println("Initialization complete..."); + + long start = System.currentTimeMillis(); + + for (int step = 0; step < steps; step++) { + doStep(MEG); + } + + long end = System.currentTimeMillis(); + float secs = ((float)(end-start))/1000.0F; + +// checkTrees(); + + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(1); + System.out.println("\nTook " + nf.format(secs) + " sec in steady state."); + nf.setMaximumFractionDigits(2); + System.out.println("Allocated " + steps + " Mb of young gen garbage" + + " (= " + nf.format(((float)steps)/secs) + + " Mb/sec)"); + System.out.println(" (actually allocated " + + nf.format(((float) youngBytes)/MEG) + " megabytes)"); + float promoted = ((float)steps) / (float)promoteRate; + System.out.println("Promoted " + promoted + + " Mb (= " + nf.format(promoted/secs) + " Mb/sec)"); + System.out.println(" (actually promoted " + + nf.format(((float) (nodes * BYTES_PER_NODE))/MEG) + + " megabytes)"); + if (ptrMutRate != 0) { + System.out.println("Mutated " + actuallyMut + + " pointers (= " + + nf.format(actuallyMut/secs) + " ptrs/sec)"); + + } + // This output serves mainly to discourage optimization. + System.out.println("Checksum = " + (mutatorSum + aexport.length)); + + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Tue Jan 20 10:22:44 2015 -0800 @@ -37,6 +37,7 @@ public class ByteCodeLoader extends SecureClassLoader { private final String className; private final byte[] byteCode; + private volatile Class holder; /** * Creates a new {@code ByteCodeLoader} ready to load a class with the @@ -51,6 +52,21 @@ } @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (!name.equals(className)) { + return super.loadClass(name); + } + if (holder == null) { + synchronized(this) { + if (holder == null) { + holder = findClass(name); + } + } + } + return holder; + } + + @Override protected Class findClass(String name) throws ClassNotFoundException { if (!name.equals(className)) { throw new ClassNotFoundException(name); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Tue Jan 20 10:22:44 2015 -0800 @@ -54,7 +54,9 @@ try { while (true) { target.run(); - Thread.sleep(mills); + if (mills > 0) { + Thread.sleep(mills); + } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Tue Jan 20 10:22:44 2015 -0800 @@ -34,6 +34,7 @@ private static final String osArch = System.getProperty("os.arch"); private static final String vmName = System.getProperty("java.vm.name"); private static final String userName = System.getProperty("user.name"); + private static final String compiler = System.getProperty("sun.management.compiler"); public static boolean isClient() { return vmName.endsWith(" Client VM"); @@ -55,6 +56,10 @@ return vmName.contains("Embedded"); } + public static boolean isTieredSupported() { + return compiler.contains("Tiered Compilers"); + } + public static boolean is32bit() { return dataModel.equals("32"); } diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Tue Jan 20 10:22:44 2015 -0800 @@ -40,6 +40,7 @@ import java.util.Collections; import java.util.List; import java.util.Random; +import java.util.function.BooleanSupplier; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -306,25 +307,6 @@ } /** - * Returns file content as a list of strings - * - * @param file File to operate on - * @return List of strings - * @throws IOException - */ - public static List fileAsList(File file) throws IOException { - assertTrue(file.exists() && file.isFile(), - file.getAbsolutePath() + " does not exist or not a file"); - List output = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) { - while (reader.ready()) { - output.add(reader.readLine().replace(NEW_LINE, "")); - } - } - return output; - } - - /** * Return the contents of the named file as a single String, * or null if not found. * @param filename name of the file to read @@ -396,6 +378,52 @@ } /** + * Wait for condition to be true + * + * @param condition, a condition to wait for + */ + public static final void waitForCondition(BooleanSupplier condition) { + waitForCondition(condition, -1L, 100L); + } + + /** + * Wait until timeout for condition to be true + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true + * specifying -1 will wait forever + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout) { + return waitForCondition(condition, timeout, 100L); + } + + /** + * Wait until timeout for condition to be true for specified time + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true, + * specifying -1 will wait forever + * @param sleepTime a time to sleep value in milliseconds + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout, long sleepTime) { + long startTime = System.currentTimeMillis(); + while (!(condition.getAsBoolean() || (timeout != -1L + && ((System.currentTimeMillis() - startTime) > timeout)))) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + return condition.getAsBoolean(); + } + + /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted * @return The timeout value adjusted for the value of "test.timeout.factor" diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.java.testlibrary.dtrace; + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public interface DtraceResultsAnalyzer { + public void analyze(OutputAnalyzer oa, String logFilePath); +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.java.testlibrary.dtrace; + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.OutputAnalyzer; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class DtraceRunner { + + private static final String DTRACE_DEFAULT_PATH = "/usr/sbin/dtrace"; + private static final String DTRACE_PATH_PROPERTY + = "com.oracle.test.dtrace.path"; + private static final String OUTPUT_FILE_DTRACE_OPTION = "o"; + private static final String RUN_COMMAND_DTRACE_OPTION = "c"; + private static final String RUN_SCRIPT_DTRACE_OPTION = "s"; + private static final String ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION = "Z"; + private static final String DTRACE_OPTION_PREFIX = "-"; + public static final String PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION = "w"; + public static final String DTRACE_OUT_LOG = "dtrace.out"; + + private final String dtraceExecutable; + + public DtraceRunner() { + dtraceExecutable = getDtracePath(); + } + + private List getLaunchCmd(String java, String javaOpts, + String execClass, String testArgs, String dtraceScript, + String dtraceAddOpts) { + Asserts.assertTrue(!java.matches("\\s"), "Current dtrace implementation" + + " can't handle whitespaces in application path"); + List result = new ArrayList<>(); + result.add(dtraceExecutable); + result.add(DTRACE_OPTION_PREFIX + System.getProperty("sun.arch.data.model")); + result.add(DTRACE_OPTION_PREFIX + + ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION + + ((dtraceAddOpts == null) ? "" : dtraceAddOpts) + + RUN_SCRIPT_DTRACE_OPTION); // run_script should be last one + result.add(dtraceScript); + result.add(DTRACE_OPTION_PREFIX + OUTPUT_FILE_DTRACE_OPTION); + result.add(DTRACE_OUT_LOG); + result.add(DTRACE_OPTION_PREFIX + RUN_COMMAND_DTRACE_OPTION); + result.add(java + " " + javaOpts + " " + execClass + " " + testArgs); + return result; + } + + private void backupLogFile(File file) { + if (file.exists()) { + file.renameTo(new File(file.getPath() + ".bak")); + } + } + + public void runDtrace(String java, String javaOpts, String execClass, + String testArgs, String dtraceScript, String dtraceAddOpts, + DtraceResultsAnalyzer analyzer) { + backupLogFile(new File(DTRACE_OUT_LOG)); + ProcessBuilder pbuilder = new ProcessBuilder( + getLaunchCmd(java, javaOpts, execClass, testArgs, + dtraceScript, dtraceAddOpts)); + OutputAnalyzer oa; + try { + oa = new OutputAnalyzer(pbuilder.start()); + } catch (IOException e) { + throw new Error("TESTBUG: Can't start process", e); + } + analyzer.analyze(oa, DTRACE_OUT_LOG); + } + + public static boolean dtraceAvailable() { + String path = getDtracePath(); + if (path == null) { + return false; + } + // now we'll launch dtrace to trace itself just to be sure it works + // and have all additional previleges set + ProcessBuilder pbuilder = new ProcessBuilder(path, path); + try { + OutputAnalyzer oa = new OutputAnalyzer(pbuilder.start()); + if (oa.getExitValue() != 0) { + return false; + } + } catch (IOException e) { + throw new Error("Couldn't launch dtrace", e); + } + return true; + } + + private static String getDtracePath() { + String propPath = System.getProperty(DTRACE_PATH_PROPERTY); + if (propPath != null && new File(propPath).exists()) { + return propPath; + } else if (new File(DTRACE_DEFAULT_PATH).exists()) { + return DTRACE_DEFAULT_PATH; + } + return null; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/Bar.java --- a/hotspot/test/testlibrary/ctw/test/Bar.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -public class Bar { - private static void staticMethod() { } - public void method() { } - protected Bar() { } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/ClassesDirTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main ClassesDirTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes - * @run main ClassesDirTest check ctw.log - * @summary testing of CompileTheWorld :: classes in directory - * @author igor.ignatyev@oracle.com - */ - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class ClassesDirTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# dir: classes", "Done (2 classes, 6 methods, "}; - - private ClassesDirTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new ClassesDirTest().run(args); - } - - protected void prepare() throws Exception { - String path = "classes"; - Files.createDirectory(Paths.get(path)); - Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"), - StandardCopyOption.REPLACE_EXISTING); - Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"), - StandardCopyOption.REPLACE_EXISTING); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/ClassesListTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main ClassesListTest prepare - * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst - * @run main ClassesListTest check ctw.log - * @summary testing of CompileTheWorld :: list of classes in file - * @author igor.ignatyev@oracle.com - */ - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class ClassesListTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# list: classes.lst", "Done (4 classes, "}; - - private ClassesListTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new ClassesListTest().run(args); - } - - protected void prepare() throws Exception { - String path = "classes.lst"; - Files.copy(Paths.get(System.getProperty("test.src"), path), - Paths.get(path), StandardCopyOption.REPLACE_EXISTING); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/CtwTest.java --- a/hotspot/test/testlibrary/ctw/test/CtwTest.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.util.List; -import java.util.Collections; -import java.util.ArrayList; - -import java.io.File; -import java.io.Writer; -import java.io.FileWriter; -import java.io.IOException; -import java.io.BufferedReader; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.nio.charset.Charset; - -import com.oracle.java.testlibrary.JDKToolFinder; -import com.oracle.java.testlibrary.OutputAnalyzer; - -public abstract class CtwTest { - protected final String[] shouldContain; - protected CtwTest(String[] shouldContain) { - this.shouldContain = shouldContain; - } - - public void run(String[] args) throws Exception { - if (args.length == 0) { - throw new Error("args is empty"); - } - switch (args[0]) { - case "prepare": - prepare(); - break; - case "check": - check(args); - break; - default: - throw new Error("unregonized action -- " + args[0]); - } - } - - protected void prepare() throws Exception { } - - protected void check(String[] args) throws Exception { - if (args.length < 2) { - throw new Error("logfile isn't specified"); - } - String logfile = args[1]; - try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile), - Charset.defaultCharset())) { - OutputAnalyzer output = readOutput(r); - for (String test : shouldContain) { - output.shouldContain(test); - } - } - } - - private static OutputAnalyzer readOutput(BufferedReader reader) - throws IOException { - StringBuilder builder = new StringBuilder(); - String eol = String.format("%n"); - String line; - - while ((line = reader.readLine()) != null) { - builder.append(line); - builder.append(eol); - } - return new OutputAnalyzer(builder.toString(), ""); - } - - protected void dump(OutputAnalyzer output, String name) { - try (Writer w = new FileWriter(name + ".out")) { - String s = output.getStdout(); - w.write(s, s.length(), 0); - } catch (IOException io) { - io.printStackTrace(); - } - try (Writer w = new FileWriter(name + ".err")) { - String s = output.getStderr(); - w.write(s, s.length(), 0); - } catch (IOException io) { - io.printStackTrace(); - } - } - - protected ProcessBuilder createJarProcessBuilder(String... command) - throws Exception { - String javapath = JDKToolFinder.getJDKTool("jar"); - - ArrayList args = new ArrayList<>(); - args.add(javapath); - Collections.addAll(args, command); - - return new ProcessBuilder(args.toArray(new String[args.size()])); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/Foo.java --- a/hotspot/test/testlibrary/ctw/test/Foo.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -public class Foo { - private static void staticMethod() { } - public void method() { } - protected Foo() { } -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/JarDirTest.java --- a/hotspot/test/testlibrary/ctw/test/JarDirTest.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main JarDirTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/* - * @run main JarDirTest check ctw.log - * @summary testing of CompileTheWorld :: jars in directory - * @author igor.ignatyev@oracle.com - */ - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Paths; - -import com.oracle.java.testlibrary.OutputAnalyzer; - -public class JarDirTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# jar_in_dir: jars", - "# jar: jars" + File.separator +"foo.jar", - "# jar: jars" + File.separator +"bar.jar", - "Done (4 classes, 12 methods, "}; - - private JarDirTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new JarDirTest().run(args); - } - - protected void prepare() throws Exception { - String path = "jars"; - Files.createDirectory(Paths.get(path)); - - ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar", - "Foo.class", "Bar.class"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-foo.jar"); - output.shouldHaveExitValue(0); - - pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class", - "Bar.class"); - output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-bar.jar"); - output.shouldHaveExitValue(0); - } - -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/JarsTest.java --- a/hotspot/test/testlibrary/ctw/test/JarsTest.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8012447 - * @library /testlibrary /../../test/lib /testlibrary/ctw/src - * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar - * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main JarsTest prepare - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar - * @run main JarsTest check ctw.log - * @summary testing of CompileTheWorld :: jars - * @author igor.ignatyev@oracle.com - */ - -import com.oracle.java.testlibrary.OutputAnalyzer; - -public class JarsTest extends CtwTest { - private static final String[] SHOULD_CONTAIN - = {"# jar: foo.jar", "# jar: bar.jar", - "Done (4 classes, 12 methods, "}; - - private JarsTest() { - super(SHOULD_CONTAIN); - } - - public static void main(String[] args) throws Exception { - new JarsTest().run(args); - } - - protected void prepare() throws Exception { - ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar", - "Foo.class", "Bar.class"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-foo.jar"); - output.shouldHaveExitValue(0); - - pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class"); - output = new OutputAnalyzer(pb.start()); - dump(output, "ctw-bar.jar"); - output.shouldHaveExitValue(0); - } - -} diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary/ctw/test/classes.lst --- a/hotspot/test/testlibrary/ctw/test/classes.lst Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -java.lang.String -java.lang.Object -Foo -Bar diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Jan 15 19:23:49 2015 -0800 +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Tue Jan 20 10:22:44 2015 -0800 @@ -48,7 +48,7 @@ OS("isLinux", "isSolaris", "isWindows", "isOSX"), VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"), IGNORED("isEmbedded", "isDebugBuild", "shouldSAAttach", - "canPtraceAttachLinux", "canAttachOSX"); + "canPtraceAttachLinux", "canAttachOSX", "isTieredSupported"); public final List methodNames; diff -r 6b55dd30a0ba -r 0388b3b63648 hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.Platform; +import sun.hotspot.WhiteBox; + +/** + * @test + * @summary Verifies that Platform::isTieredSupported returns correct value. + * @library /testlibrary /../../test/lib + * @build TestPlatformIsTieredSupported + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * TestPlatformIsTieredSupported + */ +public class TestPlatformIsTieredSupported { + public static void main(String args[]) { + WhiteBox whiteBox = WhiteBox.getWhiteBox(); + boolean tieredCompilation = whiteBox.getBooleanVMFlag( + "TieredCompilation"); + Asserts.assertEQ(Platform.isTieredSupported(), tieredCompilation, + "Platform::isTieredSupported should report the same value as " + + "TieredCompilation flag's value when " + + "+TieredCompilation was explicitly passed to JVM."); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/.hgtags --- a/jaxp/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 40b242363040229a05224fbc5dc203a3f46a8f8f jdk9-b43 0cb0844b58924d6086d2850c22087d06679d5eef jdk9-b44 0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45 +74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,64 +23,59 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; - import java.io.File; -import java.io.IOException; - import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; +import static javax.xml.parsers.ptests.ParserTestConst.GOLDEN_DIR; +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; - +import jaxp.library.JAXPFileBaseTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * This tests DocumentBuilderFactory for namespace processing and no-namespace * processing. */ -public class DBFNamespaceTest { +public class DBFNamespaceTest extends JAXPFileBaseTest { /** * Provide input for the cases that supporting namespace or not. + * @return a two-dimensional array contains factory, output file name and + * golden validate file name. */ @DataProvider(name = "input-provider") public Object[][] getInput() { DocumentBuilderFactory dbf1 = DocumentBuilderFactory.newInstance(); - String outputfile1 = USER_DIR + FILE_SEP + "dbfnstest01.out"; - String goldfile1 = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfnstest01GF.out"; + String outputfile1 = USER_DIR + "dbfnstest01.out"; + String goldfile1 = GOLDEN_DIR + "dbfnstest01GF.out"; DocumentBuilderFactory dbf2 = DocumentBuilderFactory.newInstance(); dbf2.setNamespaceAware(true); - String outputfile2 = USER_DIR + FILE_SEP + "dbfnstest02.out"; - String goldfile2 = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfnstest02GF.out"; + String outputfile2 = USER_DIR + "dbfnstest02.out"; + String goldfile2 = GOLDEN_DIR + "dbfnstest02GF.out"; return new Object[][] { { dbf1, outputfile1, goldfile1 }, { dbf2, outputfile2, goldfile2 } }; } /** * Test to parse and transform a document without supporting namespace and * with supporting namespace. + * @param dbf a Document Builder factory for creating document object. + * @param outputfile output file name. + * @param goldfile golden validate file name. + * @throws Exception If any errors occur. */ @Test(dataProvider = "input-provider") - public void testNamespaceTest(DocumentBuilderFactory dbf, String outputfile, String goldfile) { - try { - Document doc = dbf.newDocumentBuilder().parse(new File(TestUtils.XML_DIR, "namespace1.xml")); - dummyTransform(doc, outputfile); - assertTrue(compareWithGold(goldfile, outputfile)); - } catch (SAXException | IOException | ParserConfigurationException | TransformerFactoryConfigurationError | TransformerException e) { - failUnexpected(e); - } + public void testNamespaceTest(DocumentBuilderFactory dbf, String outputfile, + String goldfile) throws Exception { + Document doc = dbf.newDocumentBuilder().parse(new File(XML_DIR, "namespace1.xml")); + dummyTransform(doc, outputfile); + assertTrue(compareWithGold(goldfile, outputfile)); } /** @@ -89,16 +84,14 @@ * not chosen, namespaceURI in callbacks should be an empty string otherwise * it should be namespaceURI. * - * @throws TransformerFactoryConfigurationError - * @throws TransformerException - * @throws IOException + * @throws Exception If any errors occur. */ - private void dummyTransform(Document document, String fileName) throws TransformerFactoryConfigurationError, TransformerException, IOException { + private void dummyTransform(Document document, String fileName) + throws Exception { DOMSource domSource = new DOMSource(document); - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - File file = new File(fileName); - System.out.println("The fileName is " + file.getAbsolutePath()); - transformer.transform(domSource, new SAXResult(MyCHandler.newInstance(file))); + try(MyCHandler chandler = MyCHandler.newInstance(new File(fileName))) { + TransformerFactory.newInstance().newTransformer(). + transform(domSource, new SAXResult(chandler)); + } } - } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,451 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * This checks the methods of DocumentBuilderFactoryImpl - */ -public class DocumentBuilderFactory01 { - /** - * Testcase to test the default functionality of schema support method. - */ - @Test - public void testCheckSchemaSupport1() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - dbf.setNamespaceAware(true); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "test.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of schema support method. In - * this case the schema source property is set. - */ - @Test - public void testCheckSchemaSupport2() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - dbf.setNamespaceAware(true); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", new InputSource(new FileInputStream( - new File(TestUtils.XML_DIR, "test.xsd")))); - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "test1.xml")); - assertFalse(eh.errorOccured); - } catch (IllegalArgumentException | ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the default functionality of schema support method. In - * this case the schema source property is set. - */ - @Test - public void testCheckSchemaSupport3() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(true); - spf.setNamespaceAware(true); - SAXParser sp = spf.newSAXParser(); - sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", - new InputSource(new FileInputStream(new File(TestUtils.XML_DIR, "test.xsd")))); - DefaultHandler dh = new DefaultHandler(); - sp.parse(new File(TestUtils.XML_DIR, "test1.xml"), dh); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of newInstance method. To test - * the isCoalescing method and setCoalescing This checks to see if the CDATA - * and text nodes got combined In that case it will print "<xml>This - * is not parsed</xml> yet". - */ - @Test - public void testCheckDocumentBuilderFactory02() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setCoalescing(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory01.xml")); - Element e = (Element) doc.getElementsByTagName("html").item(0); - NodeList nl = e.getChildNodes(); - assertEquals(nl.item(0).getNodeValue().trim(), "This is not parsed yet"); - } catch (IOException | SAXException | ParserConfigurationException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the isIgnoringComments. By default it is false. - */ - @Test - public void testCheckDocumentBuilderFactory03() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - assertFalse(dbf.isIgnoringComments()); - } - - /** - * Testcase to test the isValidating. By default it is false, set it to true - * and then use a document which is not valid. It should throw a warning or - * an error at least. The test passes in case retval 0 is set in the error - * method . - */ - @Test - public void testCheckDocumentBuilderFactory04() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory05.xml")); - assertTrue(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setValidating. By default it is false, use a - * document which is not valid. It should not throw a warning or an error. - * The test passes in case the retval equals 1 . - */ - @Test - public void testCheckDocumentBuilderFactory16() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory05.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the setValidating. By default it is false, use a - * document which is valid. It should not throw a warning or an error. The - * test passes in case the retval equals 1. - */ - @Test - public void testCheckDocumentBuilderFactory17() { - try { - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory04.xml")); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * To test the isExpandEntityReferences. By default it is true. - */ - @Test - public void testCheckDocumentBuilderFactory05() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertTrue(dbf.isExpandEntityReferences()); - assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the default functionality of setValidating method. The - * xml file has a DTD which has namespaces defined. The parser takes care to - * check if the namespaces using elements and defined attributes are there - * or not. - */ - @Test - public void testCheckDocumentBuilderFactory06() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - MyErrorHandler eh = MyErrorHandler.newInstance(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory04.xml")); - assertTrue(doc instanceof Document); - assertFalse(eh.errorOccured); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the setExpandEntityReferences. - */ - @Test - public void testCheckDocumentBuilderFactory07() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setExpandEntityReferences(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertTrue(dbf.isExpandEntityReferences()); - assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setExpandEntityReferences. - */ - @Test - public void testCheckDocumentBuilderFactory08() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setExpandEntityReferences(false); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory02.xml"))); - Element e = (Element) doc.getElementsByTagName("title").item(0); - NodeList nl = e.getChildNodes(); - assertNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setIgnoringComments. By default it is set to false. - * explicitly setting it to false, it recognizes the comment which is in - * Element Node Hence the Element's child node is not null. - */ - @Test - public void testCheckDocumentBuilderFactory09() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setIgnoringComments(false); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertNotNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - - } - - /** - * This tests for the parse(InputSource). - */ - @Test - public void testCheckDocumentBuilderFactory10() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new InputSource(new BufferedReader(new FileReader(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))))); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse InputStream with SystemID as a second parameter. - */ - @Test - public void testCheckDocumentBuilderFactory11() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "dbf10import.xsl")), new File(TestUtils.XML_DIR).toURI() - .toASCIIString()); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse InputStream with empty SystemID as a second - * parameter. - */ - @Test - public void testCheckDocumentBuilderFactory12() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "dbf10import.xsl")), " "); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse(uri). - */ - @Test - public void testCheckDocumentBuilderFactory13() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR + FILE_SEP + "dbf10import.xsl").toURI().toASCIIString()); - assertTrue(doc instanceof Document); - } catch (IllegalArgumentException | ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse (uri) with empty string as parameter should - * throw Sax Exception. - * - * @throws SAXException - * If any parse errors occur. - */ - @Test(expectedExceptions = SAXException.class) - public void testCheckDocumentBuilderFactory14() throws SAXException { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.parse(""); - } catch (ParserConfigurationException | IOException e) { - failUnexpected(e); - } - } - - /** - * This tests for the parse (uri) with null uri as parameter should throw - * IllegalArgumentException. - * - */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckDocumentBuilderFactory15() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - String uri = null; - docBuilder.parse(uri); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setIgnoringComments. By default it is set to false, - * setting this to true, It does not recognize the comment, Here the - * nodelist has a length 0 because the ignoring comments is true. - */ - @Test - public void testCheckIgnoringComments() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setIgnoringComments(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory08.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertEquals(nl.getLength(), 0); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase to test the default behaviour of setIgnoringComments. By default - * it is set to false, this is similar to case 9 but not setIgnoringComments - * explicitly, it does not recognize the comment. - */ - @Test - public void testCheckIgnoringComments1() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderFactory07.xml"))); - Element e = (Element) doc.getElementsByTagName("body").item(0); - NodeList nl = e.getChildNodes(); - assertFalse(dbf.isIgnoringComments()); - assertNotNull(nl.item(0).getNodeValue()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; -import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; - -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -/** - * This tests the setIgnoringElementWhitespace and setIgnoringComments of - * DocumentBuilderFactory - */ -public class DocumentBuilderFactory02 { - - /** - * This testcase tests for the isIgnoringElementContentWhitespace and the - * setIgnoringElementContentWhitespace. The xml file has all kinds of - * whitespace,tab and newline characters, it uses the MyNSContentHandler - * which does not invoke the characters callback when this - * setIgnoringElementContentWhitespace is set to true. - */ - @Test - public void testCheckElementContentWhitespace() { - try { - String goldFile = TestUtils.GOLDEN_DIR + FILE_SEP + "dbfactory02GF.out"; - String outputFile = USER_DIR + FILE_SEP + "dbfactory02.out"; - MyErrorHandler eh = MyErrorHandler.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - assertFalse(dbf.isIgnoringElementContentWhitespace()); - dbf.setIgnoringElementContentWhitespace(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - db.setErrorHandler(eh); - Document doc = db.parse(new File(TestUtils.XML_DIR, "DocumentBuilderFactory06.xml")); - assertFalse(eh.errorOccured); - DOMSource domSource = new DOMSource(doc); - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); - SAXResult saxResult = new SAXResult(); - saxResult.setHandler(MyCHandler.newInstance(new File(outputFile))); - transformer.transform(domSource, saxResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException | TransformerException e) { - failUnexpected(e); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,462 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.xml.parsers.ptests; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilePermission; +import java.io.FileReader; +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import static javax.xml.parsers.ptests.ParserTestConst.GOLDEN_DIR; +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * This checks the methods of DocumentBuilderFactoryImpl. + */ +public class DocumentBuilderFactoryTest extends JAXPFileBaseTest { + /** + * Test the default functionality of schema support method. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport1() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + dbf.setNamespaceAware(true); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "test.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the default functionality of schema support method. In + * this case the schema source property is set. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport2() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "test.xsd"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + dbf.setNamespaceAware(true); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", + new InputSource(fis)); + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "test1.xml")); + assertFalse(eh.isErrorOccured()); + } + } + + /** + * Test the default functionality of schema support method. In + * this case the schema source property is set. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckSchemaSupport3() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "test.xsd"))) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); + spf.setNamespaceAware(true); + SAXParser sp = spf.newSAXParser(); + sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", + W3C_XML_SCHEMA_NS_URI); + sp.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", + new InputSource(fis)); + DefaultHandler dh = new DefaultHandler(); + // Not expect any unrecoverable error here. + sp.parse(new File(XML_DIR, "test1.xml"), dh); + } + } + + /** + * Test the default functionality of newInstance method. To test + * the isCoalescing method and setCoalescing This checks to see if the CDATA + * and text nodes got combined In that case it will print "<xml>This + * is not parsed</xml> yet". + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory02() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setCoalescing(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new File(XML_DIR, "DocumentBuilderFactory01.xml")); + Element e = (Element) doc.getElementsByTagName("html").item(0); + NodeList nl = e.getChildNodes(); + assertEquals(nl.getLength(), 1); + } + + /** + * Test the isIgnoringComments. By default it is false. + */ + @Test + public void testCheckDocumentBuilderFactory03() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + assertFalse(dbf.isIgnoringComments()); + } + + /** + * Test the isValidating. By default it is false, set it to true and then + * use a document which is not valid. It should throw a warning or + * an error at least. The test passes in case retval 0 is set in the error + * method . + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory04() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml")); + assertTrue(eh.isErrorOccured()); + } + + /** + * Test the setValidating. By default it is false, use a + * document which is not valid. It should not throw a warning or an error. + * The test passes in case the return value equals 1. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory16() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory05.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the setValidating. By default it is false, use a + * document which is valid. It should not throw a warning or an error. The + * test passes in case the return value equals 1. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory17() throws Exception { + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml")); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the isExpandEntityReferences. By default it is true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory05() throws Exception { + try(FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertTrue(dbf.isExpandEntityReferences()); + assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); + } + } + + /** + * Test the default functionality of setValidating method. The + * XML file has a DTD which has namespaces defined. The parser takes care to + * check if the namespaces using elements and defined attributes are there + * or not. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory06() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + MyErrorHandler eh = MyErrorHandler.newInstance(); + db.setErrorHandler(eh); + Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory04.xml")); + assertTrue(doc instanceof Document); + assertFalse(eh.isErrorOccured()); + } + + /** + * Test the setExpandEntityReferences. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory07() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setExpandEntityReferences(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertTrue(dbf.isExpandEntityReferences()); + assertEquals(nl.item(0).getNodeValue().trim().charAt(0), 'W'); + } + } + + /** + * Test the setExpandEntityReferences. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory08() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory02.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setExpandEntityReferences(false); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("title").item(0); + NodeList nl = e.getChildNodes(); + assertNull(nl.item(0).getNodeValue()); + } + } + + /** + * Test the setIgnoringComments. By default it is set to false. + * explicitly setting it to false, it recognizes the comment which is in + * Element Node Hence the Element's child node is not null. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory09() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory07.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringComments(false); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertNotNull(nl.item(0).getNodeValue()); + } + } + + /** + * This tests for the parse(InputSource). + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory10() throws Exception { + try (BufferedReader br = new BufferedReader(new FileReader(new File( + XML_DIR, "DocumentBuilderFactory07.xml")))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new InputSource(br)); + assertNotNull(doc); + } + } + + /** + * This tests for the parse InputStream with SystemID as a second parameter. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory11() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "dbf10import.xsl"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis, new File(XML_DIR).toURI() + .toASCIIString()); + assertNotNull(doc); + } + } + + /** + * This tests for the parse InputStream with empty SystemID as a second + * parameter. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory12() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "dbf10import.xsl"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis, " "); + assertNotNull(doc); + } + } + + /** + * This tests for the parse(uri). + * @throws Exception If any errors occur. + */ + @Test + public void testCheckDocumentBuilderFactory13() throws Exception { + // Accesing default working directory. + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir + "/*", "read")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(new File(XML_DIR + "dbf10import.xsl") + .toURI().toASCIIString()); + assertNotNull(doc); + } + + /** + * This tests for the parse(uri) with empty string as parameter should + * throw Sax Exception. + * @throws Exception If any errors occur. + */ + @Test(expectedExceptions = SAXException.class) + public void testCheckDocumentBuilderFactory14() throws Exception { + // Accesing default working directory. + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.parse(""); + } + + /** + * This tests for the parse (uri) with null uri as parameter should throw + * IllegalArgumentException. + * @throws Exception If any errors occur. + * + */ + @Test(expectedExceptions = IllegalArgumentException.class) + public void testCheckDocumentBuilderFactory15() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + String uri = null; + docBuilder.parse(uri); + } + + /** + * Test the setIgnoringComments. By default it is set to false, + * setting this to true, It does not recognize the comment, Here the + * nodelist has a length 0 because the ignoring comments is true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckIgnoringComments() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory08.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringComments(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertEquals(nl.getLength(), 0); + } + } + + /** + * Test the default behaviour of setIgnoringComments. By default + * it is set to false, this is similar to case 9 but not setIgnoringComments + * explicitly, it does not recognize the comment. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckIgnoringComments1() throws Exception { + try (FileInputStream fis = new FileInputStream(new File( + XML_DIR, "DocumentBuilderFactory07.xml"))) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document doc = docBuilder.parse(fis); + Element e = (Element) doc.getElementsByTagName("body").item(0); + NodeList nl = e.getChildNodes(); + assertFalse(dbf.isIgnoringComments()); + assertNotNull(nl.item(0).getNodeValue()); + } + } + + /** + * Test for the isIgnoringElementContentWhitespace and the + * setIgnoringElementContentWhitespace. The xml file has all kinds of + * whitespace,tab and newline characters, it uses the MyNSContentHandler + * which does not invoke the characters callback when this + * setIgnoringElementContentWhitespace is set to true. + * @throws Exception If any errors occur. + */ + @Test + public void testCheckElementContentWhitespace() throws Exception { + String goldFile = GOLDEN_DIR + "dbfactory02GF.out"; + String outputFile = USER_DIR + "dbfactory02.out"; + MyErrorHandler eh = MyErrorHandler.newInstance(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setValidating(true); + assertFalse(dbf.isIgnoringElementContentWhitespace()); + dbf.setIgnoringElementContentWhitespace(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setErrorHandler(eh); + Document doc = db.parse(new File(XML_DIR, "DocumentBuilderFactory06.xml")); + assertFalse(eh.isErrorOccured()); + DOMSource domSource = new DOMSource(doc); + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); + SAXResult saxResult = new SAXResult(); + try(MyCHandler handler = MyCHandler.newInstance(new File(outputFile))) { + saxResult.setHandler(handler); + transformer.transform(domSource, saxResult); + } + assertTrue(compareWithGold(goldFile, outputFile)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,33 +24,32 @@ package javax.xml.parsers.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; - import java.io.File; import java.io.FileInputStream; -import java.io.IOException; - +import java.io.FilePermission; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * This checks for the methods of DocumentBuilder */ -public class DocumentBuilderImpl01 implements EntityResolver { - +public class DocumentBuilderImpl01 extends JAXPFileReadOnlyBaseTest + implements EntityResolver { /** * Provide DocumentBuilder. * - * @throws ParserConfigurationException + * @return data provider has single DocumentBuilder. + * @throws ParserConfigurationException if a DocumentBuilder cannot be + * created which satisfies the configuration requested. */ @DataProvider(name = "builder-provider") public Object[][] getBuilder() throws ParserConfigurationException { @@ -60,17 +59,18 @@ } /** - * Testcase to test the default functionality of isValidation method. Expect + * Test the default functionality of isValidation method. Expect * to return false because not setting the validation. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl01(DocumentBuilder docBuilder) { assertFalse(docBuilder.isValidating()); - } /** - * Testcase to test the default functionality of isNamespaceAware method. + * Test the default functionality of isNamespaceAware method. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl02(DocumentBuilder docBuilder) { @@ -78,51 +78,71 @@ } /** - * Testcase to test the parse(InputStream). + * Test the parse(InputStream). + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl04(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderImpl01.xml"))); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl04(DocumentBuilder docBuilder) + throws Exception { + try (FileInputStream fis = new FileInputStream(new File(XML_DIR, + "DocumentBuilderImpl01.xml"))) { + assertNotNull(docBuilder.parse(fis)); } } /** - * Testcase to test the parse(File). + * Test the parse(File). + * + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl05(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new File(TestUtils.XML_DIR, "DocumentBuilderImpl01.xml")); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl05(DocumentBuilder docBuilder) + throws Exception { + assertNotNull(docBuilder.parse(new File(XML_DIR, + "DocumentBuilderImpl01.xml"))); + } + + /** + * Test the parse(InputStream,systemId). + * @param docBuilder document builder instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "builder-provider") + public void testCheckDocumentBuilderImpl06(DocumentBuilder docBuilder) + throws Exception { + setPermissions(new FilePermission(XML_DIR + "../-", + "read")); + try (FileInputStream fis = new FileInputStream(new File(XML_DIR, + "DocumentBuilderImpl02.xml"))) { + assertNotNull(docBuilder.parse(fis, new File(XML_DIR).toURI() + .toASCIIString() + FILE_SEP)); } } /** - * Testcase to test the parse(InputStream,systemId). - */ - @Test(dataProvider = "builder-provider") - public void testCheckDocumentBuilderImpl06(DocumentBuilder docBuilder) { - try { - Document doc = docBuilder.parse(new FileInputStream(new File(TestUtils.XML_DIR, "DocumentBuilderImpl02.xml")), new File(TestUtils.XML_DIR).toURI() - .toASCIIString() + FILE_SEP); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the setEntityResolver. + * Test the setEntityResolver. + * @param docBuilder document builder instance. */ @Test(dataProvider = "builder-provider") public void testCheckDocumentBuilderImpl07(DocumentBuilder docBuilder) { docBuilder.setEntityResolver(this); - resolveEntity("publicId", "http://www.myhost.com/today"); + assertNotNull(resolveEntity("publicId", "http://www.myhost.com/today")); } + /** + * Allow the application to resolve external entities. + * + * @param publicId The public identifier of the external entity + * being referenced, or null if none was supplied. + * @param systemId The system identifier of the external entity + * being referenced. + * @return An InputSource object describing the new input source, + * or null to request that the parser open a regular + * URI connection to the system identifier. + */ + @Override public InputSource resolveEntity(String publicId, String systemId) { if (systemId.equals("http://www.myhost.com/today")) return new InputSource(systemId); diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPBaseTest; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -35,7 +36,7 @@ * Class containing the test cases for SAXParserFactory/DocumentBuilderFactory * newInstance methods. */ -public class FactoryConfErrorTest { +public class FactoryConfErrorTest extends JAXPBaseTest { /** * Set properties DocumentBuilderFactory and SAXParserFactory to invalid @@ -43,8 +44,8 @@ */ @BeforeTest public void setup() { - System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "xx"); - System.setProperty("javax.xml.parsers.SAXParserFactory", "xx"); + setSystemProperty("javax.xml.parsers.DocumentBuilderFactory", "xx"); + setSystemProperty("javax.xml.parsers.SAXParserFactory", "xx"); } /** @@ -53,8 +54,8 @@ */ @AfterTest public void cleanup() { - System.clearProperty("javax.xml.parsers.DocumentBuilderFactory"); - System.clearProperty("javax.xml.parsers.SAXParserFactory"); + setSystemProperty("javax.xml.parsers.DocumentBuilderFactory", null); + setSystemProperty("javax.xml.parsers.SAXParserFactory", null); } /** @@ -67,7 +68,7 @@ } /** - * To test exeception thrown if javax.xml.parsers.DocumentBuilderFactory is + * To test exception thrown if javax.xml.parsers.DocumentBuilderFactory is * invalid. */ @Test(expectedExceptions = FactoryConfigurationError.class) diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,24 +22,16 @@ */ package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import jaxp.library.JAXPBaseTest; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; /** - * Class containing the test cases for SAXParserFactory API + * Class containing the test cases for SAXParserFactory API. */ -public class SAXParserFactTest { +public class SAXParserFactTest extends JAXPBaseTest { private static final String NAMESPACES = "http://xml.org/sax/features/namespaces"; private static final String NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes"; @@ -49,20 +41,17 @@ private static final String EXTERNAL_P_ENTITIES = "http://xml.org/sax/features/external-parameter-entities"; /** - * Testcase to test if newSAXParser() method returns SAXParser. + * Test if newSAXParser() method returns SAXParser. + * @throws Exception If any errors occur. */ @Test - public void testParser01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxparser = spf.newSAXParser(); - } catch (ParserConfigurationException | SAXException e) { - failUnexpected(e); - } + public void testParser01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.newSAXParser(); } /** - * Testcase to test the default functionality (No validation) of the parser. + * Test the default functionality (No validation) of the parser. */ @Test public void testValidate01() { @@ -71,7 +60,7 @@ } /** - * Testcase to test the functionality of setValidating and isvalidating + * Test the functionality of setValidating and isvalidating * methods. */ @Test @@ -82,7 +71,7 @@ } /** - * Parser should not be namespaceaware by default. + * Parser should not be namespace-aware by default. */ @Test public void testNamespace01() { @@ -91,7 +80,7 @@ } /** - * Testcase to test the functionality of setNamespaceAware and + * Test the functionality of setNamespaceAware and * isNamespaceAware methods. */ @Test @@ -102,167 +91,132 @@ } /** - * Testcase to test the functionality of setNamespaceAware and getFeature() + * Test the functionality of setNamespaceAware and getFeature() * methods for namespaces property. + * @throws Exception If any errors occur. */ @Test - public void testFeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(NAMESPACES)); + public void testFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(NAMESPACES)); - spf.setNamespaceAware(true); - assertTrue(spf.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setNamespaceAware(true); + assertTrue(spf.getFeature(NAMESPACES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for namespaces property. + * @throws Exception If any errors occur. */ @Test - public void testFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); + public void testFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACES, true); - assertTrue(spf.getFeature(NAMESPACES)); + spf.setFeature(NAMESPACES, true); + assertTrue(spf.getFeature(NAMESPACES)); - spf.setFeature(NAMESPACES, false); - assertFalse(spf.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setFeature(NAMESPACES, false); + assertFalse(spf.getFeature(NAMESPACES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for namespace-prefixes property. + * @throws Exception If any errors occur. */ @Test - public void testFeature03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); + public void testFeature03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + spf.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - spf.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + spf.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); } /** - * Testcase to test the functionality of getFeature method for + * Test the functionality of getFeature method for * string-interning property. + * @throws Exception If any errors occur. */ @Test - public void testFeature04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(STRING_INTERNING)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(STRING_INTERNING)); } /** - * Testcase to test the functionality of getFeature and setValidating + * Test the functionality of getFeature and setValidating * methods for validation property. + * @throws Exception If any errors occur. */ @Test - public void testFeature05() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(VALIDATION)); - spf.setValidating(true); - assertTrue(spf.getFeature(VALIDATION)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature05() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(VALIDATION)); + spf.setValidating(true); + assertTrue(spf.getFeature(VALIDATION)); } /** - * Testcase to test the functionality of setFeature and getFeature methods + * Test the functionality of setFeature and getFeature methods * for validation property. + * @throws Exception If any errors occur. */ @Test - public void testFeature06() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - - spf.setFeature(VALIDATION, true); - assertTrue(spf.getFeature(VALIDATION)); - - spf.setFeature(VALIDATION, false); - assertFalse(spf.getFeature(VALIDATION)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature06() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(VALIDATION, true); + assertTrue(spf.getFeature(VALIDATION)); + spf.setFeature(VALIDATION, false); + assertFalse(spf.getFeature(VALIDATION)); } /** - * Testcase to test the functionality of getFeature method for + * Test the functionality of getFeature method for * external-general-entities property. + * @throws Exception If any errors occur. */ @Test - public void testFeature07() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(EXTERNAL_G_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature07() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(EXTERNAL_G_ENTITIES)); + } + /** + * Test the functionality of setFeature and getFeature methods + * for external-general-entities property. + * @throws Exception If any errors occur. + */ + @Test + public void testFeature08() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(EXTERNAL_G_ENTITIES, false); + assertFalse(spf.getFeature(EXTERNAL_G_ENTITIES)); } /** - * Testcase to test the functionality of setFeature and getFeature methods - * for external-general-entities property. + * Test the functionality of getFeature method for + * external-parameter-entities property. + * @throws Exception If any errors occur. */ @Test - public void testFeature08() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(EXTERNAL_G_ENTITIES, false); - assertFalse(spf.getFeature(EXTERNAL_G_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } + public void testFeature09() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertTrue(spf.getFeature(EXTERNAL_P_ENTITIES)); } /** - * Testcase to test the functionality of getFeature method for - * external-parameter-entities property. + * Test the functionality of setFeature method for + * external-parameter-entitie property. + * @throws Exception If any errors occur. */ @Test - public void testFeature09() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertTrue(spf.getFeature(EXTERNAL_P_ENTITIES)); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - } - - /** - * Testcase to test the functionality of setFeature method for - * external-parameter-entitie property. - */ - @Test - public void testFeature10() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(EXTERNAL_P_ENTITIES, false); - } catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { - failUnexpected(e); - } - + public void testFeature10() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(EXTERNAL_P_ENTITIES, false); + assertFalse(spf.getFeature(EXTERNAL_P_ENTITIES)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,14 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; - import java.io.File; import java.io.FileInputStream; +import java.io.FilePermission; import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.xml.sax.HandlerBase; @@ -43,16 +41,15 @@ /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest { - +public class SAXParserTest extends JAXPFileReadOnlyBaseTest { /** * Provide SAXParser. * - * @throws SAXException - * @throws ParserConfigurationException + * @return a data provider contains a SAXParser instance. + * @throws Exception If any errors occur. */ @DataProvider(name = "parser-provider") - public Object[][] getParser() throws ParserConfigurationException, SAXException { + public Object[][] getParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxparser = spf.newSAXParser(); return new Object[][] { { saxparser } }; @@ -62,498 +59,454 @@ * Test case with FileInputStream null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse01(SAXParser saxparser) throws IllegalArgumentException { - try { - FileInputStream instream = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse01(SAXParser saxparser) throws Exception { + FileInputStream instream = null; + saxparser.parse(instream, new HandlerBase()); } /** - * Testcase with an error in xml file, parsing should fail and throw - * SAXException. + * Test with by setting URI as null, parsing should fail and throw + * IllegalArgumentException. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse02(SAXParser saxparser) throws SAXException { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - saxparser.parse(instream, handler); - } catch (IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse02(SAXParser saxparser) throws Exception { + String uri = null; + saxparser.parse(uri, new HandlerBase()); } /** - * Testcase with a valid in xml file, parser should parse the xml document. + * Test with non-existence URI, parsing should fail and throw IOException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse03(SAXParser saxparser) { + @Test(expectedExceptions = { SAXException.class }, + dataProvider = "parser-provider") + public void testParse03(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); try { - HandlerBase handler = new HandlerBase(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - } catch (IOException | SAXException e) { - failUnexpected(e); + saxparser.parse("", new HandlerBase()); + } finally { + setPermissions(); } } /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. + * Test with File null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse04(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse04(SAXParser saxparser) throws Exception { + File file = null; + saxparser.parse(file, new HandlerBase()); } /** - * Testcase with valid input source, parser should parse the xml document - * successfully. + * Test with empty string as File, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse05(SAXParser saxparser) { + @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") + public void testParse05(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "parsertest.xml")); - saxparser.parse(instream, handler, new File(TestUtils.XML_DIR).toURI().toASCIIString()); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with uri null, parsing should fail and throw - * IllegalArgumentException. - * - * @throws IllegalArgumentException - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse07(SAXParser saxparser) throws IllegalArgumentException { - try { - String uri = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(uri, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + saxparser.parse(new File(""), new HandlerBase()); + } finally { + setPermissions(); } } /** - * Testcase with non-existant uri, parsing should fail and throw - * IOException. + * Test with input source null, parsing should fail and throw + * IllegalArgumentException. * - * @throws SAXException - * @throws IOException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = { SAXException.class, IOException.class }, dataProvider = "parser-provider") - public void testParse08(SAXParser saxparser) throws SAXException, IOException { - String uri = " "; - - HandlerBase handler = new HandlerBase(); - saxparser.parse(uri, handler); - + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse06(SAXParser saxparser) throws Exception { + InputSource is = null; + saxparser.parse(is, new HandlerBase()); } /** - * Testcase with proper uri, parser should parse successfully. + * Test with FileInputStream null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse09(SAXParser saxparser) { - try { - File file = new File(TestUtils.XML_DIR, "correct.xml"); - HandlerBase handler = new HandlerBase(); - saxparser.parse(file.toURI().toASCIIString(), handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse07(SAXParser saxparser) throws Exception { + FileInputStream instream = null; + saxparser.parse(instream, new DefaultHandler()); } /** - * Testcase with File null, parsing should fail and throw + * Test with URI null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse10(SAXParser saxparser) throws IllegalArgumentException { - try { - File file = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse08(SAXParser saxparser) throws Exception { + String uri = null; + saxparser.parse(uri, new DefaultHandler()); } /** - * Testcase with empty string as File, parsing should fail and throw - * SAXException. + * Test with non-existence URI, parsing should fail and throw + * SAXException or IOException. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse11(SAXParser saxparser) throws SAXException { + @Test(expectedExceptions = { SAXException.class, IOException.class }, + dataProvider = "parser-provider") + public void testParse09(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir + "/../-", "read")); + String uri = " "; try { - HandlerBase handler = new HandlerBase(); - File file = new File(""); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); + saxparser.parse(uri, new DefaultHandler()); + } finally { + setPermissions(); } } /** - * Testcase with xml file that has errors parsing should fail and throw + * Test with empty string as File, parsing should fail and throw * SAXException. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse12(SAXParser saxparser) throws SAXException { + public void testParse10(SAXParser saxparser) throws Exception { + String workingDir = getSystemProperty("user.dir"); + setPermissions(new FilePermission(workingDir, "read")); + File file = new File(""); try { - HandlerBase handler = new HandlerBase(); - File file = new File(TestUtils.XML_DIR, "valid.xml"); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); + saxparser.parse(file, new DefaultHandler()); + } finally { + setPermissions(); } } /** - * Testcase with xml file that has no errors Parser should successfully - * parse the xml document. + * Test with File null, parsing should fail and throw + * IllegalArgumentException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse13(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - File file = new File(TestUtils.XML_DIR, "correct.xml"); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse11(SAXParser saxparser) throws Exception { + saxparser.parse((File) null, new DefaultHandler()); } /** - * Testcase with input source null, parsing should fail and throw + * Test with input source null, parsing should fail and throw * IllegalArgumentException. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse14(SAXParser saxparser) throws IllegalArgumentException { - try { - InputSource is = null; - HandlerBase handler = new HandlerBase(); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(expectedExceptions = IllegalArgumentException.class, + dataProvider = "parser-provider") + public void testParse12(SAXParser saxparser) throws Exception { + InputSource is = null; + saxparser.parse(is, new DefaultHandler()); + } + + /** + * Test with an error in XML file, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse13(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File( + XML_DIR, "invalid.xml"))) { + saxparser.parse(instream, new HandlerBase()); } } /** - * Testcase with input source attached an invaild xml, parsing should fail - * and throw SAXException. + * Test with a valid in XML file, parser should parse the XML document. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse15(SAXParser saxparser) throws SAXException { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (IOException e) { - failUnexpected(e); - } + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse14(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "parsertest.xml"), + new HandlerBase()); } /** - * Testcase with input source attached an vaild xml, parser should - * successfully parse the xml document. + * Test with valid input stream, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse16(SAXParser saxparser) { - try { - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse15(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { + saxparser.parse(instream, new HandlerBase()); } } /** - * Testcase with FileInputStream null, parsing should fail and throw - * IllegalArgumentException. + * Test with valid input source, parser should parse the XML document + * successfully. * - * @throws IllegalArgumentException - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse17(SAXParser saxparser) throws IllegalArgumentException { - try { - FileInputStream instream = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with an error in xml file, parsing should fail and throw - * SAXException. - * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse18(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - saxparser.parse(instream, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse19(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - } catch (IOException | SAXException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse16(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "parsertest.xml"))) { + saxparser.parse(instream, new HandlerBase(), + new File(XML_DIR).toURI().toASCIIString()); } } /** - * Testcase with valid input stream, parser should parse the xml document - * successfully. + * Test with proper URI, parser should parse successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse17(SAXParser saxparser) throws Exception { + File file = new File(XML_DIR, "correct.xml"); + saxparser.parse(file.toURI().toASCIIString(), new HandlerBase()); + } + + /** + * Test with XML file that has errors parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse20(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - saxparser.parse(instream, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse18(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "valid.xml"), new HandlerBase()); + } + + /** + * Test with XML file that has no errors Parser should successfully + * parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse19(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "correct.xml"), new HandlerBase()); + } + + /** + * Test with input source attached an invalid XML, parsing should fail + * and throw SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse20(SAXParser saxparser) throws Exception { + try(FileInputStream instream = new FileInputStream(new File(XML_DIR, + "invalid.xml"))) { + saxparser.parse(new InputSource(instream), new HandlerBase()); } } /** - * Testcase with valid input source, parser should parse the xml document - * successfully. + * Test with input source attached an valid XML, parser should + * successfully parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse21(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "parsertest.xml")); - saxparser.parse(instream, handler, new File(TestUtils.XML_DIR).toURI().toASCIIString()); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - - } - - /** - * Testcase with uri null, parsing should fail and throw - * IllegalArgumentException. - * - * @throws IllegalArgumentException - */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse23(SAXParser saxparser) throws IllegalArgumentException { - try { - String uri = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(uri, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse21(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { + saxparser.parse(new InputSource(instream), new HandlerBase()); } } /** - * Testcase with non-existant uri, parsing should fail and throw - * SAXException or IOException. + * Test with an error in xml file, parsing should fail and throw + * SAXException. * - * @throws SAXException - * @throws IOException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = { SAXException.class, IOException.class }, dataProvider = "parser-provider") - public void testParse24(SAXParser saxparser) throws SAXException, IOException { - String uri = " "; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(uri, handler); - - } - - /** - * Testcase with proper uri, parser should parse successfully. - */ - @Test(dataProvider = "parser-provider") - public void testParse25(SAXParser saxparser) { - try { - File file = new File(TestUtils.XML_DIR, "correct.xml"); - - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(file.toURI().toASCIIString(), handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse22(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "invalid.xml"))) { + saxparser.parse(instream, new DefaultHandler()); } } /** - * Testcase with File null, parsing should fail and throw - * IllegalArgumentException. + * Test with valid input stream, parser should parse the XML document + * successfully. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse26(SAXParser saxparser) throws IllegalArgumentException { - try { + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse23(SAXParser saxparser) throws Exception { + DefaultHandler handler = new DefaultHandler(); + saxparser.parse(new File(XML_DIR, "parsertest.xml"), handler); + } + + /** + * Test with valid input stream, parser should parse the XML document + * successfully. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse24(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream(new File(XML_DIR, + "correct.xml"))) { DefaultHandler handler = new DefaultHandler(); - saxparser.parse((File) null, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + saxparser.parse(instream, handler); } } /** - * Testcase with empty string as File, parsing should fail and throw - * SAXException. + * Test with valid input source, parser should parse the XML document + * successfully. * - * @throws SAXException - */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse27(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(""); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with xml file that has errors, parsing should fail and throw - * SAXException. - * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse28(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(TestUtils.XML_DIR, "valid.xml"); - saxparser.parse(file, handler); - } catch (IOException e) { - failUnexpected(e); - } - } - - /** - * Testcase with xml file that has no errors, parser should successfully - * parse the xml document. - */ - @Test(dataProvider = "parser-provider") - public void testParse29(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - File file = new File(TestUtils.XML_DIR, "correct.xml"); - saxparser.parse(file, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse25(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "parsertest.xml"))) { + saxparser.parse(instream, new DefaultHandler(), + new File(XML_DIR).toURI().toASCIIString()); } } /** - * Testcase with input source null, parsing should fail and throw - * IllegalArgumentException. + * Test with proper URI, parser should parse successfully. * - * @throws IllegalArgumentException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse26(SAXParser saxparser) throws Exception { + File file = new File(XML_DIR, "correct.xml"); + saxparser.parse(file.toURI().toASCIIString(), new DefaultHandler()); + } + + /** + * Test with XML file that has errors, parsing should fail and throw + * SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "parser-provider") - public void testParse30(SAXParser saxparser) throws IllegalArgumentException { - try { - InputSource is = null; - DefaultHandler handler = new DefaultHandler(); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse27(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "valid.xml"), new DefaultHandler()); + } + + /** + * Test with XML file that has no errors, parser should successfully + * parse the XML document. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse28(SAXParser saxparser) throws Exception { + saxparser.parse(new File(XML_DIR, "correct.xml"), new DefaultHandler()); + } + + /** + * Test with an invalid XML file, parser should throw SAXException. + * + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. + */ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class, + dataProvider = "parser-provider") + public void testParse29(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "invalid.xml"))) { + saxparser.parse(new InputSource(instream), new DefaultHandler()); } } /** - * Testcase with an invalid xml file, parser should throw SAXException. + * Test case to parse an XML file that not use namespaces. * - * @throws SAXException + * @param saxparser a SAXParser instance. + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class, dataProvider = "parser-provider") - public void testParse31(SAXParser saxparser) throws SAXException { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "invalid.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (IOException e) { - failUnexpected(e); + @Test(groups = {"readLocalFiles"}, dataProvider = "parser-provider") + public void testParse30(SAXParser saxparser) throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "correct.xml"))) { + saxparser.parse(new InputSource(instream), new DefaultHandler()); } } /** - * Test case to parse an xml file that not use namespaces. + * Test case to parse an XML file that uses namespaces. + * + * @throws Exception If any errors occur. */ - @Test(dataProvider = "parser-provider") - public void testParse32(SAXParser saxparser) { - try { - DefaultHandler handler = new DefaultHandler(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "correct.xml")); - InputSource is = new InputSource(instream); - saxparser.parse(is, handler); - } catch (SAXException | IOException e) { - failUnexpected(e); - } - } - - /** - * Test case to parse an xml file that uses namespaces. - */ - @Test - public void testParse33() { - try { + @Test(groups = {"readLocalFiles"}) + public void testParse31() throws Exception { + try (FileInputStream instream = new FileInputStream( + new File(XML_DIR, "ns4.xml"))) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - HandlerBase handler = new HandlerBase(); - FileInputStream instream = new FileInputStream(new File(TestUtils.XML_DIR, "ns4.xml")); - saxparser.parse(instream, handler); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); + spf.newSAXParser().parse(instream, new HandlerBase()); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,260 +23,239 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; - -import javax.xml.parsers.FactoryConfigurationError; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import org.xml.sax.Parser; import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; -import org.xml.sax.XMLReader; import org.xml.sax.ext.DeclHandler; import org.xml.sax.ext.LexicalHandler; /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest02 { - final String DOM_NODE = "http://xml.org/sax/properties/dom-node"; - final String XML_STRING = "http://xml.org/sax/properties/xml-string"; - final String DECL_HANDLER = "http://xml.org/sax/properties/declaration-handler"; - final String LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; +public class SAXParserTest02 extends JAXPBaseTest { + private static final String DOM_NODE = "http://xml.org/sax/properties/dom-node"; + private static final String XML_STRING = "http://xml.org/sax/properties/xml-string"; + private static final String DECL_HANDLER = "http://xml.org/sax/properties/declaration-handler"; + private static final String LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; /** * Provide SAXParser. * - * @throws SAXException - * @throws ParserConfigurationException + * @return a data provider contains a SAXParser instance. + * @throws Exception If any errors occur. */ @DataProvider(name = "parser-provider") - public Object[][] getParser() throws ParserConfigurationException, SAXException { + public Object[][] getParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxparser = spf.newSAXParser(); return new Object[][] { { saxparser } }; } /** - * Testcase to test the default functionality (No validation) of the parser. + * Test to test the default functionality (No validation) of the parser. + * + * @param saxparser a SAXParser instance. */ @Test(dataProvider = "parser-provider") public void testValidate01(SAXParser saxparser) { - try { - assertFalse(saxparser.isValidating()); - } catch (FactoryConfigurationError e) { - failUnexpected(e); - } - + assertFalse(saxparser.isValidating()); } /** - * Testcase to test the functionality of setValidating and isvalidating + * Test to test the functionality of setValidating and isValidating * methods. + * + * @throws Exception If any errors occur. */ @Test - public void testValidate02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setValidating(true); - spf.newSAXParser(); - assertTrue(spf.isValidating()); - } catch (FactoryConfigurationError | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } - + public void testValidate02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setValidating(true); + spf.newSAXParser(); + assertTrue(spf.isValidating()); } /** - * Test case to test isNamespaceAware() method. By default, namespaces are + * Test isNamespaceAware() method. By default, namespaces are * not supported. + * + * @param saxparser a SAXParser instance. */ @Test(dataProvider = "parser-provider") public void testNamespace01(SAXParser saxparser) { - try { - assertFalse(saxparser.isNamespaceAware()); - } catch (FactoryConfigurationError e) { - failUnexpected(e); - } - + assertFalse(saxparser.isNamespaceAware()); } /** * Test case to test setnamespaceAware() method. + * + * @throws Exception If any errors occur. */ @Test - public void testNamespace02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - assertTrue(saxparser.isNamespaceAware()); - } catch (FactoryConfigurationError | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } - + public void testNamespace02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxparser = spf.newSAXParser(); + assertTrue(saxparser.isNamespaceAware()); } /** * Test case to test if the getParser() method returns instance of Parser. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testParser01(SAXParser saxparser) { - try { - Parser parser = saxparser.getParser(); - } catch (FactoryConfigurationError | SAXException e) { - failUnexpected(e); - } - + public void testParser01(SAXParser saxparser) throws SAXException { + assertNotNull(saxparser.getParser()); } /** * Test case to test if the getXMLReader() method returns instance of * XMLReader. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testXmlReader01(SAXParser saxparser) { - try { - XMLReader xmlReader = saxparser.getXMLReader(); - } catch (FactoryConfigurationError | SAXException e) { - failUnexpected(e); - } + public void testXmlReader01(SAXParser saxparser) throws SAXException { + assertNotNull(saxparser.getXMLReader()); } /** * Test whether the xml-string property is not supported. * - * @throws SAXNotSupportedException + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ - @Test(expectedExceptions = SAXNotSupportedException.class, dataProvider = "parser-provider") - public void testProperty01(SAXParser saxparser) throws SAXNotSupportedException { - try { - Object object = saxparser.getProperty(XML_STRING); - } catch (SAXNotRecognizedException e) { - failUnexpected(e); - } + @Test(expectedExceptions = SAXNotSupportedException.class, + dataProvider = "parser-provider") + public void testProperty01(SAXParser saxparser) throws SAXException { + saxparser.getProperty(XML_STRING); } /** * Test whether the dom-node property is not supported. * - * @throws SAXNotSupportedException + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ - @Test(expectedExceptions = SAXNotSupportedException.class, dataProvider = "parser-provider") - public void testProperty02(SAXParser saxparser) throws SAXNotSupportedException { - try { - Object object = saxparser.getProperty(DOM_NODE); - } catch (SAXNotRecognizedException e) { - failUnexpected(e); - } + @Test(expectedExceptions = SAXNotSupportedException.class, + dataProvider = "parser-provider") + public void testProperty02(SAXParser saxparser) throws SAXException { + saxparser.getProperty(DOM_NODE); } /** * Test the default lexical-handler not exists. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty03(SAXParser saxparser) { - try { - assertNull(saxparser.getProperty(LEXICAL_HANDLER)); - } catch (SAXException e) { - failUnexpected(e); - } - + public void testProperty03(SAXParser saxparser) throws SAXException { + assertNull(saxparser.getProperty(LEXICAL_HANDLER)); } /** * Test the default declaration-handler not exists. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty04(SAXParser saxparser) { - - try { - assertNull(saxparser.getProperty(DECL_HANDLER)); - } catch (SAXException e) { - failUnexpected(e); - } + public void testProperty04(SAXParser saxparser) throws SAXException { + assertNull(saxparser.getProperty(DECL_HANDLER)); } /** * Test to set and get the lexical-handler. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty05(SAXParser saxparser) { - try { - MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); - saxparser.setProperty(LEXICAL_HANDLER, myLexicalHandler); - Object object = saxparser.getProperty(LEXICAL_HANDLER); - assertTrue(object instanceof LexicalHandler); - } catch (SAXException e) { - failUnexpected(e); - } + public void testProperty05(SAXParser saxparser) throws SAXException { + MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); + saxparser.setProperty(LEXICAL_HANDLER, myLexicalHandler); + assertTrue(saxparser.getProperty(LEXICAL_HANDLER) instanceof LexicalHandler); } /** * Test to set and get the declaration-handler. + * + * @param saxparser a SAXParser instance. + * @throws SAXException If any parse errors occur. */ @Test(dataProvider = "parser-provider") - public void testProperty06(SAXParser saxparser) { - try { - MyDeclHandler myDeclHandler = new MyDeclHandler(); - saxparser.setProperty(DECL_HANDLER, myDeclHandler); - Object object = saxparser.getProperty(DECL_HANDLER); - assertTrue(object instanceof DeclHandler); - } catch (SAXException e) { - failUnexpected(e); - } - + public void testProperty06(SAXParser saxparser) throws SAXException { + MyDeclHandler myDeclHandler = new MyDeclHandler(); + saxparser.setProperty(DECL_HANDLER, myDeclHandler); + assertTrue(saxparser.getProperty(DECL_HANDLER) instanceof DeclHandler); } /** - * Customized LexicalHandler used for test. + * Customized LexicalHandler used for test. An empty implementation for + * LexicalHandler. */ private class MyLexicalHandler implements LexicalHandler { + @Override public void comment(char[] ch, int start, int length) { } + @Override public void endCDATA() { } + @Override public void endDTD() { } + @Override public void endEntity(String name) { } + @Override public void startCDATA() { } + @Override public void startDTD(String name, String publicId, String systemId) { } + @Override public void startEntity(String name) { } } /** - * Customized DeclHandler used for test. + * Customized DeclHandler used for test. An empty implementation for + * DeclHandler. */ private class MyDeclHandler implements DeclHandler { + @Override public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) { } + @Override public void elementDecl(String name, String model) { } + @Override public void externalEntityDecl(String name, String publicId, String systemId) { } + @Override public void internalEntityDecl(String name, String value) { } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,17 @@ package javax.xml.parsers.ptests; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - import java.io.File; -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; +import java.io.FilePermission; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; - +import static javax.xml.parsers.ptests.ParserTestConst.XML_DIR; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.fail; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.xml.sax.SAXException; @@ -41,68 +41,70 @@ /** * Class contains the test cases for SAXParser API */ -public class SAXParserTest03 { +public class SAXParserTest03 extends JAXPFileReadOnlyBaseTest { /** * Provide SAXParserFactory. * - * @throws Exception + * @return a dimensional contains. */ @DataProvider(name = "input-provider") public Object[][] getFactory() { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); - MyErrorHandler handler = MyErrorHandler.newInstance(); - return new Object[][] { { spf, handler } }; + return new Object[][] { { spf, MyErrorHandler.newInstance() } }; } /** * parsertest.xml holds a valid document. This method tests the validating * parser. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate01(SAXParserFactory spf, MyErrorHandler handler) { - try { - SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "parsertest.xml"), handler); - assertFalse(handler.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate01(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { + spf.newSAXParser().parse(new File(XML_DIR, "parsertest.xml"), handler); + assertFalse(handler.isErrorOccured()); } /** * validns.xml holds a valid document with XML namespaces in it. This method * tests the Validating parser with namespace processing on. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate02(SAXParserFactory spf, MyErrorHandler handler) { - try { + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate02(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "validns.xml"), handler); - assertFalse(handler.errorOccured); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + spf.newSAXParser().parse(new File(XML_DIR, "validns.xml"), handler); + assertFalse(handler.isErrorOccured()); } /** * invalidns.xml holds an invalid document with XML namespaces in it. This * method tests the validating parser with namespace processing on. It * should throw validation error. + * + * @param spf a Parser factory. + * @param handler an error handler for capturing events. + * @throws Exception If any errors occur. */ - @Test(dataProvider = "input-provider") - public void testParseValidate03(SAXParserFactory spf, MyErrorHandler handler) { + @Test(groups = {"readLocalFiles"}, dataProvider = "input-provider") + public void testParseValidate03(SAXParserFactory spf, MyErrorHandler handler) + throws Exception { try { spf.setNamespaceAware(true); SAXParser saxparser = spf.newSAXParser(); - saxparser.parse(new File(TestUtils.XML_DIR, "invalidns.xml"), handler); - failUnexpected(new RuntimeException()); - } catch (ParserConfigurationException | SAXException | IOException e) { - if (e instanceof SAXException) { - assertTrue(handler.errorOccured); - } + saxparser.parse(new File(XML_DIR, "invalidns.xml"), handler); + fail("Expecting SAXException here"); + } catch (SAXException e) { + assertTrue(handler.isErrorOccured()); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.parsers.ptests; - -import static jaxp.library.JAXPTestUtilities.ERROR_MSG_HEADER; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; - -import org.xml.sax.Attributes; -import org.xml.sax.Locator; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.LocatorImpl; - -/** - * Utility interface which includes final variables of xml, golden file - * directories. - */ -interface TestUtils { - final String XML_DIR = System.getProperty("test.src", ".") + FILE_SEP + "javax/xml/parsers/xmlfiles"; - final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out"; -} - -/** - * Customized DefaultHandler which writes output document when methods are - * called by Transformer. Test may use output document to compare with golden - * file for verification. - */ -class MyCHandler extends DefaultHandler { - - private final BufferedWriter bWriter; - private final Locator locator = new LocatorImpl(); - - private MyCHandler(File file) throws IOException { - bWriter = new BufferedWriter(new FileWriter(file)); - } - - public static MyCHandler newInstance(File file) throws IOException { - MyCHandler handler = new MyCHandler(file); - return handler; - } - - public void characters(char[] ch, int start, int length) { - String s = new String(ch, start, length); - String str = String.format("characters...length is:%d\n<%s>", s.length(), s); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void endDocument() { - String str = "endDocument..."; - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - bWriter.flush(); - bWriter.close(); - - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void endElement(String namespaceURI, String localName, String qName) { - String str = String.format("endElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s>", namespaceURI, localName, qName); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void endPrefixMapping(String prefix) { - String str = String.format("endPrefixMapping...\nprefix: <%s>", prefix); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void ignorableWhitespace(char[] ch, int start, int length) { - String s = new String(ch, start, length); - String str = String.format("ignorableWhitespace...\n%s ignorable white space string length: %d", s, s.length()); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void processingInstruction(String target, String data) { - String str = String.format("processingInstruction...target:<%s> data: <%s>", target, data); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void skippedEntity(String name) { - String str = String.format("skippedEntity...\nname: <%s>", name); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void startDocument() { - String str = "startDocument..."; - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { - String str = String.format("startElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s> Number of Attributes: <%d> Line# <%d>", namespaceURI, - localName, qName, atts.getLength(), locator.getLineNumber()); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } - - public void startPrefixMapping(String prefix, String uri) { - String str = String.format("startPrefixMapping...\nprefix: <%s> uri: <%s>", prefix, uri); - try { - bWriter.write(str, 0, str.length()); - bWriter.newLine(); - } catch (IOException e) { - throw new RuntimeException(ERROR_MSG_HEADER, e); - } - } -} - -/** - * Customized DefaultHandler used for SAXParseException testing. - */ -class MyErrorHandler extends DefaultHandler { - boolean errorOccured = false; - - private MyErrorHandler() { - } - - public static MyErrorHandler newInstance() { - return new MyErrorHandler(); - } - - public void error(SAXParseException e) { - errorOccured = true; - } - - public void warning(SAXParseException e) { - errorOccured = true; - } - - public void fatalError(SAXParseException e) { - errorOccured = true; - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.xml.transform.ptests; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; +import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.w3c.dom.Attr; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * DOM parse on test file to be compared with golden output file. No Exception + * is expected. + */ +public class DOMResultTest extends JAXPFileBaseTest { + /** + * Unit test for simple DOM parsing. + * @throws Exception If any errors occur. + */ + @Test + public void testcase01() throws Exception { + String resultFile = USER_DIR + "domresult01.out"; + String goldFile = GOLDEN_DIR + "domresult01GF.out"; + String xsltFile = XML_DIR + "cities.xsl"; + String xmlFile = XML_DIR + "cities.xml"; + + XMLReader reader = XMLReaderFactory.createXMLReader(); + SAXTransformerFactory saxTFactory + = (SAXTransformerFactory) TransformerFactory.newInstance(); + SAXSource saxSource = new SAXSource(new InputSource(xsltFile)); + TransformerHandler handler + = saxTFactory.newTransformerHandler(saxSource); + + DOMResult result = new DOMResult(); + + handler.setResult(result); + reader.setContentHandler(handler); + reader.parse(xmlFile); + + Node node = result.getNode(); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(resultFile))) { + writeNodes(node, writer); + } + assertTrue(compareWithGold(goldFile, resultFile)); + } + + /** + * Prints all node names, attributes to file + * @param node a node that need to be recursively access. + * @param bWriter file writer. + * @throws IOException if writing file failed. + */ + private void writeNodes(Node node, BufferedWriter bWriter) throws IOException { + String str = "Node: " + node.getNodeName(); + bWriter.write( str, 0,str.length()); + bWriter.newLine(); + + NamedNodeMap nnm = node.getAttributes(); + if (nnm != null && nnm.getLength() > 0) + for (int i=0; i 0) - for (int i=0; i { + try { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(xslFile)); + DOMSource domSource = new DOMSource(document); + StreamSource streamSource = new StreamSource(new FileInputStream(xmlFile)); + + File streamResultFile = new File(USER_DIR + file); + StreamResult streamResult = new StreamResult(streamResultFile); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(domSource); + transformer.setOutputProperties(transformProperties); + transformer.transform(streamSource, streamResult); + } catch (SAXException | IOException | ParserConfigurationException + | TransformerException ex) { + failUnexpected(ex); + } + }); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package javax.xml.transform.ptests; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Properties; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; -import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -/** - * Test a StreamResult using a file name that contains URL characters that need - * to be encoded. - */ -public class StreamResultTest01 { - /** - * Unit test for StreamResult. - */ - @Test - public void testcase01() { - // Set Transformer properties - Properties transformProperties = new Properties(); - transformProperties.put("method", "xml"); - transformProperties.put("encoding", "UTF-8"); - transformProperties.put("omit-xml-declaration", "yes"); - transformProperties.put("{http://xml.apache.org/xslt}indent-amount", "0"); - transformProperties.put("indent", "no"); - transformProperties.put("standalone", "no"); - transformProperties.put("version", "1.0"); - transformProperties.put("media-type", "text/xml"); - - String[] fileNames = { - "StreamResult01.out", - "StreamResult 02.out", - "StreamResult#03.out" - }; - - String xslFile = XML_DIR + "cities.xsl"; - String xmlFile = XML_DIR + "cities.xml"; - - Arrays.stream(fileNames).forEach(file -> { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(xslFile)); - DOMSource domSource = new DOMSource(document); - StreamSource streamSource = new StreamSource(new FileInputStream(xmlFile)); - - File streamResultFile = new File(CLASS_DIR + file); - StreamResult streamResult = new StreamResult(streamResultFile); - - Transformer transformer = TransformerFactory.newInstance().newTransformer(domSource); - transformer.setOutputProperties(transformProperties); - transformer.transform(streamSource, streamResult); - } catch (SAXException | IOException | ParserConfigurationException - | TransformerException ex) { - failUnexpected(ex); - } - }); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,11 +24,8 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; @@ -36,21 +33,20 @@ import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for SAXParserFactory API */ -public class TfClearParamTest { +public class TfClearParamTest extends JAXPFileReadOnlyBaseTest { /** - * Test xslt file. + * Test style-sheet file name. */ private final String XSL_FILE = XML_DIR + "cities.xsl"; @@ -72,193 +68,164 @@ /** * Obtains transformer's parameter with the same name that set before. Value * should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear01() { - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME).toString(), PARAM_VALUE); - } catch (TransformerConfigurationException ex) { - failUnexpected(ex); - } - + public void clear01() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME).toString(), PARAM_VALUE); } /** * Obtains transformer's parameter with the a name that wasn't set before. * Null is expected. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + @Test + public void clear02() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); + } + + /** + * Obtains transformer's parameter with a short name that set before. Value + * should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ @Test - public void clear02() { - try { - Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + public void clear03() throws TransformerConfigurationException { + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); + + transformer.setParameter(SHORT_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(SHORT_PARAM_NAME).toString(), PARAM_VALUE); + } + + /** + * Obtains transformer's parameter with a short name that set with an integer + * object before. Value should be same as the set integer object. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + @Test + public void clear04() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + + int intObject = 5; + transformer.setParameter(SHORT_PARAM_NAME, intObject); + assertEquals(transformer.getParameter(SHORT_PARAM_NAME), intObject); } /** * Obtains transformer's parameter whose initiated with a stream source with * the a name that set before. Value should be same as set one. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ - @Test - public void clear03() { - try { - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(new StreamSource(new File(XSL_FILE))); + @Test (groups = {"readLocalFiles"}) + public void clear05() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(new StreamSource(new File(XSL_FILE))); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); } /** * Obtains transformer's parameter whose initiated with a stream source with * the a name that wasn't set before. Null is expected. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ - @Test - public void clear04() { - try { - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(new StreamSource(new File(XSL_FILE))); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } - + @Test (groups = {"readLocalFiles"}) + public void clear06() throws TransformerConfigurationException { + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(new StreamSource(new File(XSL_FILE))); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); } /** * Obtains transformer's parameter whose initiated with a sax source with * the a name that set before. Value should be same as set one. + * @throws Exception If any errors occur. */ - @Test - public void clear05() { - try { - InputSource is = new InputSource(new FileInputStream(XSL_FILE)); + @Test (groups = {"readLocalFiles"}) + public void clear07() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_FILE)) { SAXSource saxSource = new SAXSource(); - saxSource.setInputSource(is); + saxSource.setInputSource(new InputSource(fis)); Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); } } /** * Obtains transformer's parameter whose initiated with a sax source with * the a name that wasn't set before. Null is expected. + * @throws Exception If any errors occur. */ - @Test - public void clear06() { - try { - InputSource is = new InputSource(new FileInputStream(XSL_FILE)); + @Test (groups = {"readLocalFiles"}) + public void clear08() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_FILE)) { SAXSource saxSource = new SAXSource(); - saxSource.setInputSource(is); + saxSource.setInputSource(new InputSource(fis)); Transformer transformer = TransformerFactory.newInstance().newTransformer(saxSource); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); transformer.clearParameters(); assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); } } /** * Obtains transformer's parameter whose initiated with a dom source with * the a name that set before. Value should be same as set one. + * @throws Exception If any errors occur. */ - @Test - public void clear07() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); + @Test (groups = {"readLocalFiles"}) + public void clear09() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_FILE)); - DOMSource domSource = new DOMSource((Node)document); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_FILE)); + DOMSource domSource = new DOMSource((Node)document); - Transformer transformer = tfactory.newTransformer(domSource); + Transformer transformer = tfactory.newTransformer(domSource); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + assertEquals(transformer.getParameter(LONG_PARAM_NAME), PARAM_VALUE); } /** * Obtains transformer's parameter whose initiated with a dom source with * the a name that wasn't set before. Null is expected. - */ - @Test - public void clear08() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_FILE)); - DOMSource domSource = new DOMSource((Node)document); - - Transformer transformer = tfactory.newTransformer(domSource); - transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); - transformer.clearParameters(); - assertNull(transformer.getParameter(LONG_PARAM_NAME)); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } - } - - /** - * Obtains transformer's parameter with a short name that set before. Value - * should be same as set one. + * @throws Exception If any errors occur. */ - @Test - public void clear09() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); - - transformer.setParameter(SHORT_PARAM_NAME, PARAM_VALUE); - assertEquals(transformer.getParameter(SHORT_PARAM_NAME).toString(), PARAM_VALUE); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } - } + @Test (groups = {"readLocalFiles"}) + public void clear10() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); - /** - * Obtains transformer's parameter with a short name that set with an integer - * object before. Value should be same as the set integer object. - */ - @Test - public void clear10() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - Transformer transformer = tfactory.newTransformer(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_FILE)); + DOMSource domSource = new DOMSource((Node)document); - int intObject = 5; - transformer.setParameter(SHORT_PARAM_NAME, intObject); - assertEquals(transformer.getParameter(SHORT_PARAM_NAME), intObject); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + Transformer transformer = tfactory.newTransformer(domSource); + transformer.setParameter(LONG_PARAM_NAME, PARAM_VALUE); + transformer.clearParameters(); + assertNull(transformer.getParameter(LONG_PARAM_NAME)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,14 @@ package javax.xml.transform.ptests; import java.io.File; +import java.io.FilePermission; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -38,13 +40,14 @@ /** * Basic test for TransformerException specification. */ -public class TransformerExcpTest { +public class TransformerExcpTest extends JAXPBaseTest { /** - * Transform an unformatted xslt file. TransformerException is thrown. + * Transform an unformatted style-sheet file. TransformerException is thrown. */ @Test public void tfexception() { try { + setPermissions(new FilePermission(XML_DIR + "-", "read")); // invalid.xsl has well-formedness error. Therefore transform throws // TransformerException StreamSource streamSource @@ -60,6 +63,8 @@ assertNotNull(e.getException()); assertNull(e.getLocationAsString()); assertEquals(e.getMessageAndLocation(),e.getMessage()); + } finally { + setPermissions(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,39 +24,35 @@ import java.io.*; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.*; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.w3c.dom.*; -import org.xml.sax.SAXException; /** * Class containing the test cases for TransformerFactory API's * getAssociatedStyleSheet method. */ -public class TransformerFactoryTest { +public class TransformerFactoryTest extends JAXPFileBaseTest { /** * This test case checks for the getAssociatedStylesheet method * of TransformerFactory. * The style sheet returned is then copied to an tfactory01.out - * It will then be verified to see if it matches the golden files + * It will then be verified to see if it matches the golden files. + * + * @throws Exception If any errors occur. */ @Test - public void tfactory01() { - String outputFile = CLASS_DIR + "tfactory01.out"; + public void tfactory01() throws Exception { + String outputFile = USER_DIR + "tfactory01.out"; String goldFile = GOLDEN_DIR + "tfactory01GF.out"; String xmlFile = XML_DIR + "TransformerFactoryTest.xml"; String xmlURI = "file:///" + XML_DIR; @@ -76,10 +72,7 @@ "Modern", null); Transformer t = tFactory.newTransformer(); t.transform(s, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException - | TransformerException | SAXException ex) { - failUnexpected(ex); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,9 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import java.util.Properties; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.ErrorListener; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; @@ -39,150 +36,132 @@ import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Basic test cases for Transformer API */ -public class TransformerTest { +public class TransformerTest extends JAXPFileReadOnlyBaseTest { /** * XSLT file serves every test method. */ private final static String TEST_XSL = XML_DIR + "cities.xsl"; /** - * This tests if newTransformer(StreamSource) method returns Transformer + * This tests if newTransformer(StreamSource) method returns Transformer. + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. */ - @Test - public void transformer01() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - StreamSource streamSource = new StreamSource( - new File(TEST_XSL)); - Transformer transformer = tfactory.newTransformer(streamSource); - assertNotNull(transformer); - } catch (TransformerConfigurationException ex){ - failUnexpected(ex); - } + @Test (groups = {"readLocalFiles"}) + public void transformer01() throws TransformerConfigurationException { + TransformerFactory tfactory = TransformerFactory.newInstance(); + StreamSource streamSource = new StreamSource( + new File(TEST_XSL)); + Transformer transformer = tfactory.newTransformer(streamSource); + assertNotNull(transformer); } /** - * This tests if newTransformer(SAXSource) method returns Transformer + * This tests if newTransformer(SAXSource) method returns Transformer. + * @throws Exception If any errors occur. */ - @Test - public void transformer02() { - try { + @Test (groups = {"readLocalFiles"}) + public void transformer02() throws Exception { + try (FileInputStream fis = new FileInputStream(TEST_XSL)) { TransformerFactory tfactory = TransformerFactory.newInstance(); - InputSource is = new InputSource( - new FileInputStream(TEST_XSL)); - SAXSource saxSource = new SAXSource(is); + SAXSource saxSource = new SAXSource(new InputSource(fis)); Transformer transformer = tfactory.newTransformer(saxSource); assertNotNull(transformer); - } catch (TransformerConfigurationException | FileNotFoundException ex){ - failUnexpected(ex); - } - } - - /** - * This tests if newTransformer(DOMSource) method returns Transformer - */ - @Test - public void transformer03() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); - - Transformer transformer = tfactory.newTransformer(domSource); - assertNotNull(transformer); - } catch (TransformerConfigurationException | IOException - | ParserConfigurationException | SAXException ex){ - failUnexpected(ex); } } /** - * This tests set/get ErrorListener methods of Transformer + * This tests if newTransformer(DOMSource) method returns Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer04() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + @Test (groups = {"readLocalFiles"}) + public void transformer03() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); + + Transformer transformer = tfactory.newTransformer(domSource); + assertNotNull(transformer); + } - Transformer transformer = TransformerFactory.newInstance() - .newTransformer(domSource); - transformer.setErrorListener(new MyErrorListener()); - assertNotNull(transformer.getErrorListener()); - assertTrue(transformer.getErrorListener() instanceof MyErrorListener); - } catch (IOException | IllegalArgumentException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + /** + * This tests set/get ErrorListener methods of Transformer. + * + * @throws Exception If any errors occur. + */ + @Test (groups = {"readLocalFiles"}) + public void transformer04() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); + + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(domSource); + transformer.setErrorListener(new MyErrorListener()); + assertNotNull(transformer.getErrorListener()); + assertTrue(transformer.getErrorListener() instanceof MyErrorListener); } /** - * This tests getOutputProperties() method of Transformer + * This tests getOutputProperties() method of Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer05() { - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + @Test (groups = {"readLocalFiles"}) + public void transformer05() throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = TransformerFactory.newInstance(). - newTransformer(domSource); - Properties prop = transformer.getOutputProperties(); + Transformer transformer = TransformerFactory.newInstance(). + newTransformer(domSource); + Properties prop = transformer.getOutputProperties(); - assertEquals(prop.getProperty("indent"), "yes"); - assertEquals(prop.getProperty("method"), "xml"); - assertEquals(prop.getProperty("encoding"), "UTF-8"); - assertEquals(prop.getProperty("standalone"), "no"); - assertEquals(prop.getProperty("version"), "1.0"); - assertEquals(prop.getProperty("omit-xml-declaration"), "no"); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException ex){ - failUnexpected(ex); - } + assertEquals(prop.getProperty("indent"), "yes"); + assertEquals(prop.getProperty("method"), "xml"); + assertEquals(prop.getProperty("encoding"), "UTF-8"); + assertEquals(prop.getProperty("standalone"), "no"); + assertEquals(prop.getProperty("version"), "1.0"); + assertEquals(prop.getProperty("omit-xml-declaration"), "no"); } /** - * This tests getOutputProperty() method of Transformer + * This tests getOutputProperty() method of Transformer. + * + * @throws Exception If any errors occur. */ - @Test - public void transformer06() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); + @Test (groups = {"readLocalFiles"}) + public void transformer06() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(TEST_XSL)); - DOMSource domSource = new DOMSource(document); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(TEST_XSL)); + DOMSource domSource = new DOMSource(document); - Transformer transformer = tfactory.newTransformer(domSource); - assertEquals(transformer.getOutputProperty("method"), "xml"); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException | IllegalArgumentException ex){ - failUnexpected(ex); - } + Transformer transformer = tfactory.newTransformer(domSource); + assertEquals(transformer.getOutputProperty("method"), "xml"); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,42 +25,34 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * Here a transformer is created using DOMSource. Some specific output property * is set on transformer. Then transform(StreamSource, StreamResult) is tested. */ -public class TransformerTest02 { +public class TransformerTest02 extends JAXPFileBaseTest { /** * Unit test for transform(StreamSource, StreamResult). + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "transformer02.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "transformer02.out"; String goldFile = GOLDEN_DIR + "transformer02GF.out"; String xsltFile = XML_DIR + "cities.xsl"; String xmlFile = XML_DIR + "cities.xml"; @@ -69,9 +61,8 @@ FileOutputStream fos = new FileOutputStream(outputFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(xsltFile)); - DOMSource domSource = new DOMSource(document); + DOMSource domSource = new DOMSource(dbf.newDocumentBuilder(). + parse(new File(xsltFile))); Transformer transformer = TransformerFactory.newInstance(). newTransformer(domSource); @@ -79,20 +70,8 @@ StreamResult streamResult = new StreamResult(fos); transformer.setOutputProperty("indent", "no"); - transformer.transform( streamSource, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | IllegalArgumentException - | ParserConfigurationException | TransformerException - | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + transformer.transform(streamSource, streamResult); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,30 +25,20 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Properties; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; -import static javax.xml.transform.ptests.TransformerTestConst.CLASS_DIR; import static javax.xml.transform.ptests.TransformerTestConst.GOLDEN_DIR; import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; /** * Here Properties Object is populated with required properties.A transformer @@ -56,13 +46,15 @@ * for transformer. Then transform(StreamSource, StreamResult) is used for * transformation. This tests the setOutputProperties() method. */ -public class TransformerTest03 { +public class TransformerTest03 extends JAXPFileBaseTest { /** * Test for Transformer.setOutputProperties method. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "transformer03.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "transformer03.out"; String goldFile = GOLDEN_DIR + "transformer03GF.out"; String xsltFile = XML_DIR + "cities.xsl"; String xmlFile = XML_DIR + "cities.xml"; @@ -81,29 +73,14 @@ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(xsltFile)); - DOMSource domSource = new DOMSource(document); + DOMSource domSource = new DOMSource(dbf.newDocumentBuilder(). + parse(new File(xsltFile))); Transformer transformer = TransformerFactory.newInstance(). newTransformer(domSource); - StreamSource streamSource = new StreamSource(fis); - StreamResult streamResult = new StreamResult(fos); - transformer.setOutputProperties(properties); - transformer.transform( streamSource, streamResult); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException - | IOException | TransformerException ex){ - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + transformer.transform(new StreamSource(fis), new StreamResult(fos)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,15 +24,10 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMSource; @@ -40,18 +35,17 @@ import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileBaseTest; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * URIResolver should be invoked when transform happens. */ -public class URIResolverTest implements URIResolver { +public class URIResolverTest extends JAXPFileBaseTest implements URIResolver { /** * System ID constant. */ @@ -72,9 +66,8 @@ */ private final static String XSL_TEMP_FILE = "temp/cities.xsl"; - /** - * expected Href. + * expected HREF. */ private final String validateHref; @@ -84,6 +77,14 @@ private final String validateBase; /** + * Default constructor for testng invocation. + */ + public URIResolverTest(){ + validateHref = null; + validateBase = null; + } + + /** * Constructor for setting expected Href and expected Base URI. * @param validateHref expected Href * @param validateBase expected Base URI @@ -110,166 +111,144 @@ /** * This is to test the URIResolver.resolve() method when a transformer is - * created using StreamSource. xsl file has xsl:include in it + * created using StreamSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver01() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver01() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_INCLUDE_FILE)) { TransformerFactory tfactory = TransformerFactory.newInstance(); URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); tfactory.setURIResolver(resolver); - StreamSource streamSource = new StreamSource(new FileInputStream(XSL_INCLUDE_FILE)); + StreamSource streamSource = new StreamSource(fis); streamSource.setSystemId(SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(streamSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(streamSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using DOMSource. xsl file has xsl:include in it + * created using DOMSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver02() { - try { - TransformerFactory tfactory = TransformerFactory.newInstance(); - URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); - tfactory.setURIResolver(resolver); + @Test (groups = {"readLocalFiles"}) + public static void resolver02() throws Exception { + TransformerFactory tfactory = TransformerFactory.newInstance(); + URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); + tfactory.setURIResolver(resolver); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(XSL_INCLUDE_FILE); - DOMSource domSource = new DOMSource(document, SYSTEM_ID); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(XSL_INCLUDE_FILE); + DOMSource domSource = new DOMSource(document, SYSTEM_ID); - Transformer transformer = tfactory.newTransformer(domSource); - } catch (IOException | ParserConfigurationException - | TransformerConfigurationException | SAXException ex){ - failUnexpected(ex); - } + assertNotNull(tfactory.newTransformer(domSource)); } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using SAXSource. xsl file has xsl:include in it + * created using SAXSource. style-sheet file has xsl:include in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver03() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver03() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_INCLUDE_FILE)){ URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - InputSource is = new InputSource(new FileInputStream(XSL_INCLUDE_FILE)); + InputSource is = new InputSource(fis); is.setSystemId(SYSTEM_ID); SAXSource saxSource = new SAXSource(is); - - Transformer transformer = tfactory.newTransformer(saxSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(saxSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using StreamSource. xsl file has xsl:import in it + * created using StreamSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver04() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver04() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_IMPORT_FILE)) { URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - - StreamSource streamSource = new StreamSource(new FileInputStream(XSL_IMPORT_FILE)); + StreamSource streamSource = new StreamSource(fis); streamSource.setSystemId(SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(streamSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(streamSource)); } } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using DOMSource. xsl file has xsl:import in it + * created using DOMSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver05() { - try { - URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); - TransformerFactory tfactory = TransformerFactory.newInstance(); - tfactory.setURIResolver(resolver); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document document = db.parse(new File(XSL_IMPORT_FILE)); - DOMSource domSource = new DOMSource(document, SYSTEM_ID); - - Transformer transformer = tfactory.newTransformer(domSource); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerConfigurationException ex){ - failUnexpected(ex); - } - + @Test (groups = {"readLocalFiles"}) + public static void resolver05() throws Exception { + URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); + TransformerFactory tfactory = TransformerFactory.newInstance(); + tfactory.setURIResolver(resolver); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document document = db.parse(new File(XSL_IMPORT_FILE)); + DOMSource domSource = new DOMSource(document, SYSTEM_ID); + assertNotNull(tfactory.newTransformer(domSource)); } /** * This is to test the URIResolver.resolve() method when a transformer is - * created using SAXSource. xsl file has xsl:import in it + * created using SAXSource. style-sheet file has xsl:import in it. + * + * @throws Exception If any errors occur. */ - @Test - public static void resolver06() { - try { + @Test (groups = {"readLocalFiles"}) + public static void resolver06() throws Exception { + try (FileInputStream fis = new FileInputStream(XSL_IMPORT_FILE)){ URIResolverTest resolver = new URIResolverTest(XSL_TEMP_FILE, SYSTEM_ID); TransformerFactory tfactory = TransformerFactory.newInstance(); tfactory.setURIResolver(resolver); - - InputSource is = new InputSource(new FileInputStream(XSL_IMPORT_FILE)); + InputSource is = new InputSource(fis); is.setSystemId(SYSTEM_ID); SAXSource saxSource = new SAXSource(is); - - Transformer transformer = tfactory.newTransformer(saxSource); - } catch (FileNotFoundException | TransformerConfigurationException ex){ - failUnexpected(ex); + assertNotNull(tfactory.newTransformer(saxSource)); } - } /** * This is to test the URIResolver.resolve() method when there is an error * in the file. + * + * @throws Exception If any errors occur. */ - @Test - public static void docResolver01() { - try { + @Test (groups = {"readLocalFiles"}) + public static void docResolver01() throws Exception { + try (FileInputStream fis = new FileInputStream(XML_DIR + "doctest.xsl")) { URIResolverTest resolver = new URIResolverTest("temp/colors.xml", SYSTEM_ID); - TransformerFactory tfactory = TransformerFactory.newInstance(); + StreamSource streamSource = new StreamSource(fis); + streamSource.setSystemId(SYSTEM_ID); - StreamSource streamSource = new StreamSource( - new FileInputStream(XML_DIR + FILE_SEP + "doctest.xsl")); - streamSource.setSystemId(SYSTEM_ID); - System.err.println(streamSource.getSystemId()); - - Transformer transformer = tfactory.newTransformer(streamSource); + Transformer transformer = TransformerFactory.newInstance().newTransformer(streamSource); transformer.setURIResolver(resolver); - File f = new File(XML_DIR + FILE_SEP + "myFake.xml"); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.parse(f); + File f = new File(XML_DIR + "myFake.xml"); + Document document = DocumentBuilderFactory.newInstance(). + newDocumentBuilder().parse(f); // Use a Transformer for output DOMSource source = new DOMSource(document); - System.err.println("Ignore the following output -- just dumping it here"); StreamResult result = new StreamResult(System.err); + // No exception is expected because resolver resolve wrong URI. transformer.transform(source, result); - } catch (IOException | ParserConfigurationException | SAXException - | TransformerException ex) { - failUnexpected(ex); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,19 +23,22 @@ package javax.xml.transform.ptests.othervm; import javax.xml.transform.*; +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.fail; import org.testng.annotations.Test; /** * Negative test for set invalid TransformerFactory property. */ -public class TFCErrorTest{ +public class TFCErrorTest extends JAXPBaseTest { @Test(expectedExceptions = ClassNotFoundException.class) public void tfce01() throws Exception { try{ - System.setProperty("javax.xml.transform.TransformerFactory","xx"); - TransformerFactory tFactory = TransformerFactory.newInstance(); - } catch (TransformerFactoryConfigurationError error) { - throw error.getException(); + setSystemProperty("javax.xml.transform.TransformerFactory","xx"); + TransformerFactory.newInstance(); + fail("Expect TransformerFactoryConfigurationError here"); + } catch (TransformerFactoryConfigurationError expected) { + throw expected.getException(); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package javax.xml.xpath.ptests; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -31,7 +31,6 @@ import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import static javax.xml.xpath.XPathConstants.BOOLEAN; import static javax.xml.xpath.XPathConstants.NODE; @@ -41,7 +40,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import static javax.xml.xpath.ptests.XPathTestConst.XML_DIR; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertEquals; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -49,12 +48,11 @@ import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for XPathExpression API. */ -public class XPathExpressionTest { +public class XPathExpressionTest extends JAXPFileReadOnlyBaseTest { /** * Document object for testing XML file. */ @@ -87,13 +85,11 @@ /** * Create Document object and XPath object for every time - * @throws ParserConfigurationException If the factory class cannot be - * loaded, instantiated - * @throws SAXException If any parse errors occur. - * @throws IOException If operation on xml file failed. + * @throws Exception If any errors occur. */ @BeforeTest - public void setup() throws ParserConfigurationException, SAXException, IOException { + public void setup() throws Exception { + setPermissions(new FilePermission(XML_PATH.toFile().toString(), "read")); document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(XML_PATH.toFile()); xpath = XPathFactory.newInstance().newXPath(); } @@ -101,230 +97,200 @@ /** * Test for evaluate(java.lang.Object item,QName returnType)throws * XPathExpressionException. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression01() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). - evaluate(document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression01() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). + evaluate(document, STRING), "6"); } /** * evaluate(java.lang.Object item,QName returnType) throws NPE if input * source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression02() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression02() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); } /** * evaluate(java.lang.Object item,QName returnType) throws NPE if returnType * is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression03() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(document, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression03() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(document, null); } /** * Test for method evaluate(java.lang.Object item,QName returnType).If a * request is made to evaluate the expression in the absence of a context * item, simple expressions, such as "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression04() { - try { - assertEquals(xpath.compile("1+1").evaluate(document, STRING), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression04() throws XPathExpressionException { + assertEquals(xpath.compile("1+1").evaluate(document, STRING), "2"); } /** * evaluate(java.lang.Object item,QName returnType) throws IAE If returnType * is not one of the types defined in XPathConstants. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPathExpression05() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(document, TEST_QNAME); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression05() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(document, TEST_QNAME); } /** * evaluate(java.lang.Object item,QName returnType) return correct boolean * value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression06() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). + public void testCheckXPathExpression06() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(document, BOOLEAN), true); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } } /** * evaluate(java.lang.Object item,QName returnType) return correct boolean * value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression07() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_B). - evaluate(document, BOOLEAN), false); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression07() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_B). + evaluate(document, BOOLEAN), false); } /** * evaluate(java.lang.Object item,QName returnType) return correct number * value when return type is Double. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression08() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NUMBER), 6d); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression08() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NUMBER), 6d); } /** * evaluate(java.lang.Object item,QName returnType) evaluate an attribute * value which returnType is Node. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression09() { - try { - Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NODE); - assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression09() throws XPathExpressionException { + Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NODE); + assertEquals(attr.getValue(), "6"); } /** * evaluate(java.lang.Object item,QName returnType) evaluate an attribute * value which returnType is NodeList. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression10() { - try { - NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). - evaluate(document, NODESET); - Attr attr = (Attr) nodeList.item(0); - assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression10() throws XPathExpressionException { + NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). + evaluate(document, NODESET); + Attr attr = (Attr) nodeList.item(0); + assertEquals(attr.getValue(), "6"); } /** * Test for evaluate(java.lang.Object item) when returnType is left off of * the XPath.evaluate method, all expressions are evaluated to a String * value. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression11() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression11() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document), "6"); } /** * evaluate(java.lang.Object item) throws NPE if expression is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression12() { - try { - xpath.compile(null).evaluate(document); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression12() throws XPathExpressionException { + xpath.compile(null).evaluate(document); } /** * evaluate(java.lang.Object item) when a request is made to evaluate the * expression in the absence of a context item, simple expressions, such as * "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathExpression13() { - try { - assertEquals(xpath.compile("1+1").evaluate(document), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression13() throws XPathExpressionException { + assertEquals(xpath.compile("1+1").evaluate(document), "2"); } /** * evaluate(java.lang.Object item) throws NPE if document is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression14() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression14() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null); } /** * valuate(InputSource source) return a string value if return type is * String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression15() { + @Test (groups = {"readLocalFiles"}) + public void testCheckXPathExpression15() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is)), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source) throws NPE if input source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression16() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression16() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null); } /** - * evaluate(InputSource source) throws NPE if expression is null + * evaluate(InputSource source) throws NPE if expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression17() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression17() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(null).evaluate(new InputSource(is)); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -332,14 +298,12 @@ * evaluate(InputSource source) throws XPathExpressionException if * returnType is String junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression18() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression18() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile("-*&").evaluate(new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -347,67 +311,63 @@ * evaluate(InputSource source) throws XPathExpressionException if * expression is a blank string " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression19() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression19() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(" ").evaluate(new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) returns a string * value if returnType is String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression20() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression20() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), STRING), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) throws NPE if source is * null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression21() { - try { - xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathExpression21() throws XPathExpressionException { + xpath.compile(EXPRESSION_NAME_A).evaluate(null, STRING); } /** * evaluate(InputSource source,QName returnType) throws NPE if expression is * null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression22() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression22() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(null).evaluate(new InputSource(is), STRING); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) throws NPE if returnType is * null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathExpression23() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPathExpression23() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), null); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -415,14 +375,12 @@ * evaluate(InputSource source,QName returnType) throws * XPathExpressionException if expression is junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression24() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression24() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile("-*&").evaluate(new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -430,14 +388,12 @@ * evaluate(InputSource source,QName returnType) throws * XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPathExpression25() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPathExpression25() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(" ").evaluate(new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -445,85 +401,85 @@ * evaluate(InputSource source,QName returnType) throws * IllegalArgumentException if returnType is not one of the types defined * in XPathConstants. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPathExpression26() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = IllegalArgumentException.class) + public void testCheckXPathExpression26() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.compile(EXPRESSION_NAME_A).evaluate(new InputSource(is), TEST_QNAME); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct boolean * value if returnType is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression27() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression27() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), BOOLEAN), true); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct boolean * value if returnType is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression28() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression28() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_B). evaluate(new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * evaluate(InputSource source,QName returnType) return a correct number * value if returnType is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression29() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression29() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) returns a node if * returnType is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression30() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression30() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { Attr attr = (Attr) xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NODE); assertEquals(attr.getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for evaluate(InputSource source,QName returnType) return a node list * if returnType is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPathExpression31() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPathExpression31() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList) xpath.compile(EXPRESSION_NAME_A). evaluate(new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,14 +26,14 @@ import static javax.xml.xpath.XPathConstants.DOM_OBJECT_MODEL; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactoryConfigurationException; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.AssertJUnit.assertNotNull; import org.testng.annotations.Test; /** * Class containing the test cases for XPathFactory API. */ -public class XPathFactoryTest { +public class XPathFactoryTest extends JAXPBaseTest { /** * Valid URL for creating a XPath factory. */ @@ -54,21 +54,21 @@ /** * XPathFactory.newInstance(String uri) throws NPE if uri is null. + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = NullPointerException.class) - private void testCheckXPathFactory02() { - try { - XPathFactory.newInstance(null); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory02() throws XPathFactoryConfigurationException { + XPathFactory.newInstance(null); } /** * XPathFactory.newInstance(String uri) throws XPFCE if uri is just a blank * string. * - * @throws XPathFactoryConfigurationException + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = XPathFactoryConfigurationException.class) public void testCheckXPathFactory03() throws XPathFactoryConfigurationException { @@ -78,21 +78,21 @@ /** * Test for constructor - XPathFactory.newInstance(String uri) with valid * url - "http://java.sun.com/jaxp/xpath/dom". + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory04() { - try { - assertNotNull(XPathFactory.newInstance(VALID_URL)); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory04() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(VALID_URL)); } /** * Test for constructor - XPathFactory.newInstance(String uri) with invalid * url - "http://java.sun.com/jaxp/xpath/dom1". * - * @throws XPathFactoryConfigurationException + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test(expectedExceptions = XPathFactoryConfigurationException.class) public void testCheckXPathFactory05() throws XPathFactoryConfigurationException { @@ -112,26 +112,24 @@ * Test for constructor - XPathFactory.newInstance(String uri) with valid * url - "http://java.sun.com/jaxp/xpath/dom" and creating XPath with * newXPath(). + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory07() { - try { - assertNotNull(XPathFactory.newInstance(VALID_URL).newXPath()); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory07() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(VALID_URL).newXPath()); } /** * Test for constructor - XPathFactory.newInstance(String uri) with valid * uri - DOM_OBJECT_MODEL.toString(). + * + * @throws XPathFactoryConfigurationException If the specified object model + * is unavailable, or if there is a configuration error. */ @Test - public void testCheckXPathFactory08() { - try { - assertNotNull(XPathFactory.newInstance(DOM_OBJECT_MODEL)); - } catch (XPathFactoryConfigurationException ex) { - failUnexpected(ex); - } + public void testCheckXPathFactory08() throws XPathFactoryConfigurationException { + assertNotNull(XPathFactory.newInstance(DOM_OBJECT_MODEL)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -34,7 +34,7 @@ /** * Class containing the test cases for XPathFunctionResolver. */ -public class XPathFunctionResolverTest { +public class XPathFunctionResolverTest extends JAXPBaseTest { /** * A XPath for evaluation environment and expressions. */ @@ -54,26 +54,22 @@ /** * Test for resolveFunction(QName functionName,int arity). evaluate will * continue as long as functionName is meaningful. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPathFunctionResolver01() { - try { - assertEquals(xpath.evaluate("round(1.7)", (Object)null), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathFunctionResolver01() throws XPathExpressionException { + assertEquals(xpath.evaluate("round(1.7)", (Object)null), "2"); } /** * Test for resolveFunction(QName functionName,int arity); evaluate throws * NPE if functionName is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPathFunctionResolver02() { - try { - assertEquals(xpath.evaluate(null, "5"), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPathFunctionResolver02() throws XPathExpressionException { + assertEquals(xpath.evaluate(null, "5"), "2"); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java --- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package javax.xml.xpath.ptests; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; @@ -33,7 +33,6 @@ import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import static javax.xml.xpath.XPathConstants.BOOLEAN; import static javax.xml.xpath.XPathConstants.NODE; @@ -43,7 +42,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import static javax.xml.xpath.ptests.XPathTestConst.XML_DIR; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; @@ -53,12 +52,11 @@ import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * Class containing the test cases for XPath API. */ -public class XPathTest { +public class XPathTest extends JAXPFileReadOnlyBaseTest { /** * Document object for testing XML file. */ @@ -91,13 +89,11 @@ /** * Create Document object and XPath object for every time - * @throws ParserConfigurationException If the factory class cannot be - * loaded, instantiated - * @throws SAXException If any parse errors occur. - * @throws IOException If operation on xml file failed. + * @throws Exception If any errors occur. */ @BeforeTest - public void setup() throws ParserConfigurationException, SAXException, IOException { + public void setup() throws Exception { + setPermissions(new FilePermission(XML_DIR + "-", "read")); document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(XML_PATH.toFile()); xpath = XPathFactory.newInstance().newXPath(); } @@ -105,62 +101,54 @@ /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType) which return type is String. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath01() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath01() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, STRING), "6"); } /** * Test for XPath.compile(java.lang.String expression) and then * evaluate(java.lang.Object item, QName returnType). + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath02() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document, STRING), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath02() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_A).evaluate(document, STRING), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item) when the third argument is left off of the XPath.evaluate method, * all expressions are evaluated to a String value. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath03() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath03() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document), "6"); } /** * Test for XPath.compile(java.lang.String expression). If expression is * null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath04() { - try { - xpath.compile(null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath04() throws XPathExpressionException { + xpath.compile(null); } /** * Test for XPath.compile(java.lang.String expression). If expression cannot * be compiled junk characters, should throw XPathExpressionException. * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath05() throws XPathExpressionException { @@ -171,7 +159,7 @@ * Test for XPath.compile(java.lang.String expression). If expression is * blank, should throw XPathExpressionException * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath06() throws XPathExpressionException { @@ -181,55 +169,46 @@ /** * Test for XPath.compile(java.lang.String expression). The expression * cannot be evaluated as this does not exist. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath07() { - try { - assertEquals(xpath.compile(EXPRESSION_NAME_B).evaluate(document, STRING), ""); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } - + public void testCheckXPath07() throws XPathExpressionException { + assertEquals(xpath.compile(EXPRESSION_NAME_B).evaluate(document, STRING), ""); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object - * item, QName returnType). If String expression is null, should throw NPE + * item, QName returnType). If String expression is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath08() { - try { - xpath.evaluate(null, document, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath08() throws XPathExpressionException { + xpath.evaluate(null, document, STRING); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If item is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath09() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath09() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null, STRING); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If returnType is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath10() { - try { - xpath.evaluate(EXPRESSION_NAME_A, document, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath10() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, document, null); } /** @@ -237,23 +216,20 @@ * item, QName returnType). If a request is made to evaluate the expression * in the absence of a context item, simple expressions, such as "1+1", can * be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath11() { - try { - assertEquals(xpath.evaluate("1+1", document, STRING), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath11() throws XPathExpressionException { + assertEquals(xpath.evaluate("1+1", document, STRING), "2"); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) throws XPathExpressionException if expression is a empty * string "". - * . * - * @throws XPathExpressionException + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = XPathExpressionException.class) public void testCheckXPath12() throws XPathExpressionException { @@ -264,161 +240,141 @@ * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) throws IllegalArgumentException if returnType is not one of * the types defined in XPathConstants. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPath13() { - try { - xpath.evaluate(EXPRESSION_NAME_A, document, TEST_QNAME); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath13() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, document, TEST_QNAME); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct boolean value if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath14() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, BOOLEAN), true); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath14() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, BOOLEAN), true); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns false as expression is not successful in evaluating * to any result if returnType is Boolean. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath15() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_B, document, BOOLEAN), false); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath15() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_B, document, BOOLEAN), false); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct number value if return type is Number. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath16() { - try { - assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, NUMBER), 6d); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath16() throws XPathExpressionException { + assertEquals(xpath.evaluate(EXPRESSION_NAME_A, document, NUMBER), 6d); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item, QName * returnType) returns correct string value if return type is Node. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath17() { - try { - assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, document, NODE)).getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath17() throws XPathExpressionException { + assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, document, NODE)).getValue(), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item, QName returnType). If return type is NodeList,the evaluated value * equals to "6" as expected. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath18() { - try { - NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, document, NODESET); - assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath18() throws XPathExpressionException { + NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, document, NODESET); + assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item). If expression is null, should throw NPE. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath19() { - try { - xpath.evaluate(null, document); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath19() throws XPathExpressionException { + xpath.evaluate(null, document); } /** * Test for XPath.evaluate(java.lang.String expression, java.lang.Object * item). If a request is made to evaluate the expression in the absence of * a context item, simple expressions, such as "1+1", can be evaluated. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test - public void testCheckXPath20() { - try { - assertEquals(xpath.evaluate("1+1", document), "2"); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath20() throws XPathExpressionException { + assertEquals(xpath.evaluate("1+1", document), "2"); } /** * XPath.evaluate(java.lang.String expression, java.lang.Object item) throws * NPE if InputSource is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath21() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath21() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null); } /** * XPath.evaluate(java.lang.String expression, InputSource source) return * correct value by looking for Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath22() { + @Test (groups = {"readLocalFiles"}) + public void testCheckXPath22() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is)), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source) throws * NPE if InputSource is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath23() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath23() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null); } /** * XPath.evaluate(java.lang.String expression, InputSource source) throws * NPE if String expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath24() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath24() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(null, new InputSource(is)); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -427,14 +383,12 @@ * If expression is junk characters, expression cannot be evaluated, should * throw XPathExpressionException. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath25() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath25() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate("-*&", new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -442,66 +396,62 @@ * XPath.evaluate(java.lang.String expression, InputSource source) throws * XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath26() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath26() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(" ", new InputSource(is)); - } catch (IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) returns correct string value which return type is String. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath27() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath27() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), STRING), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws NPE if source is null. + * + * @throws XPathExpressionException If the expression cannot be evaluated. */ @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath28() { - try { - xpath.evaluate(EXPRESSION_NAME_A, null, STRING); - } catch (XPathExpressionException ex) { - failUnexpected(ex); - } + public void testCheckXPath28() throws XPathExpressionException { + xpath.evaluate(EXPRESSION_NAME_A, null, STRING); } /** * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws NPE if expression is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath29() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath29() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(null, new InputSource(is), STRING); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, - * QName returnType) throws NPE if returnType is null . + * QName returnType) throws NPE if returnType is null. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void testCheckXPath30() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void testCheckXPath30() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), null); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -509,14 +459,12 @@ * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws XPathExpressionException if expression is junk characters. * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath31() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath31() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate("-*&", new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -524,14 +472,12 @@ * XPath.evaluate(java.lang.String expression, InputSource source, QName * returnType) throws XPathExpressionException if expression is blank " ". * - * @throws XPathExpressionException + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = XPathExpressionException.class) - public void testCheckXPath32() throws XPathExpressionException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = XPathExpressionException.class) + public void testCheckXPath32() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(" ", new InputSource(is), STRING); - } catch (IOException ex) { - failUnexpected(ex); } } @@ -539,84 +485,84 @@ * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) throws IllegalArgumentException if returnType is not * one of the types defined in XPathConstants. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = IllegalArgumentException.class) - public void testCheckXPath33() { + @Test(groups = {"readLocalFiles"}, expectedExceptions = IllegalArgumentException.class) + public void testCheckXPath33() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), TEST_QNAME); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct boolean value if return type is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath34() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath34() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), BOOLEAN), true); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct boolean value if return type is Boolean. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath35() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath35() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_B, new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct number value if return type is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath36() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath36() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) return correct string value if return type is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath37() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath37() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODE)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * Test for XPath.evaluate(java.lang.String expression, InputSource source, * QName returnType) which return type is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath38() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath38() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } @@ -624,57 +570,57 @@ * Test for XPath.evaluate(java.lang.String expression, InputSource iSource, * QName returnType). If return type is Boolean, should return false as * expression is not successful in evaluating to any result. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath52() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath52() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_B, new InputSource(is), BOOLEAN), false); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns correct number value which return type is Number. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath53() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath53() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NUMBER), 6d); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns a node value if returnType is Node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath54() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath54() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { assertEquals(((Attr)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODE)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } /** * XPath.evaluate(java.lang.String expression, InputSource iSource, QName * returnType) returns a node list if returnType is NodeList. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckXPath55() { + @Test(groups = {"readLocalFiles"}) + public void testCheckXPath55() throws Exception { try (InputStream is = Files.newInputStream(XML_PATH)) { NodeList nodeList = (NodeList)xpath.evaluate(EXPRESSION_NAME_A, new InputSource(is), NODESET); assertEquals(((Attr) nodeList.item(0)).getValue(), "6"); - } catch (XPathExpressionException | IOException ex) { - failUnexpected(ex); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ package org.xml.sax.ptests; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; @@ -30,7 +31,7 @@ /** * Class containing the test cases for AttributesImpl API. */ -public class AttrImplTest { +public class AttrImplTest extends JAXPBaseTest { private static final String CAR_URI = "http://www.cars.com/xml"; private static final String CAR_LOCALNAME = "part"; diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,13 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -45,39 +38,29 @@ * ContentHandler has Attributes as one of its arguments. Attributes * pertaining to an element are taken into this argument and various methods * of Attributes interfaces are tested. This program uses Namespace processing - * with namespaces in xml file. This program does not use Validation + * with namespaces in XML file. This program does not use Validation */ -public class AttributesNSTest { +public class AttributesNSTest extends JAXPFileBaseTest { /** * Test for Attribute Interface's setter/getter. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "AttributesNS.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "AttributesNS.out"; String goldFile = GOLDEN_DIR + "AttributesNSGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - // http://www.saxproject.com/?selected=namespaces namespace-prefixes - //set to false to supress xmlns attributes - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - false); - SAXParser saxParser = spf.newSAXParser(); - MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); - saxParser.parse(new File(xmlFile), myAttrCHandler); - myAttrCHandler.flushAndClose(); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + // http://www.saxproject.com/?selected=namespaces namespace-prefixes + //set to false to supress xmlns attributes + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + false); + SAXParser saxParser = spf.newSAXParser(); + MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); + saxParser.parse(new File(xmlFile), myAttrCHandler); + myAttrCHandler.flushAndClose(); + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,13 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -48,37 +41,28 @@ * This program uses Namespace processing without any namepsaces in xml file. * This program uses Validation */ -public class AttributesTest { +public class AttributesTest extends JAXPFileBaseTest { /** * Unit test for Attributes interface. Prints all attributes into output * file. Check it with golden file. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "Attributes.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "Attributes.out"; String goldFile = GOLDEN_DIR + "AttributesGF.out"; String xmlFile = XML_DIR + "family.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - true); - spf.setValidating(true); - SAXParser saxParser = spf.newSAXParser(); - MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); - saxParser.parse(new File(xmlFile), myAttrCHandler); - myAttrCHandler.flushAndClose(); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + spf.setValidating(true); + SAXParser saxParser = spf.newSAXParser(); + MyAttrCHandler myAttrCHandler = new MyAttrCHandler(outputFile); + saxParser.parse(new File(xmlFile), myAttrCHandler); + myAttrCHandler.flushAndClose(); + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,24 +26,18 @@ import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -52,43 +46,34 @@ * transverses XML and print all visited node when XMLreader parses XML. Test * verifies output is same as the golden file. */ -public class ContentHandlerTest { +public class ContentHandlerTest extends JAXPFileBaseTest { /** * Content event handler visit all nodes to print to output file. + * + * @throws Exception If any errors occur. */ @Test - public void testcase01() { - String outputFile = CLASS_DIR + "Content.out"; + public void testcase01() throws Exception { + String outputFile = USER_DIR + "Content.out"; String goldFile = GOLDEN_DIR + "ContentGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try(FileInputStream instream = new FileInputStream(xmlFile)) { + try(FileInputStream instream = new FileInputStream(xmlFile); + MyContentHandler cHandler = new MyContentHandler(outputFile)) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - ContentHandler cHandler = new MyContentHandler(outputFile); xmlReader.setContentHandler(cHandler); - InputSource is = new InputSource(instream); - xmlReader.parse(is); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch( IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + xmlReader.parse(new InputSource(instream)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } /** * A content write out handler. */ -class MyContentHandler extends XMLFilterImpl { +class MyContentHandler extends XMLFilterImpl implements AutoCloseable { /** * Prefix to every exception. */ @@ -258,4 +243,14 @@ throw new SAXException(WRITE_ERROR, ex); } } + + /** + * Close the writer if it's initiated. + * @throws IOException if any IO error when close buffered writer. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,15 +26,11 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.Attributes; @@ -42,7 +38,6 @@ import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,46 +45,32 @@ * XMLReader parse XML with default handler that transverses XML and * print all visited node. Test verifies output is same as the golden file. */ -public class DefaultHandlerTest { +public class DefaultHandlerTest extends JAXPFileBaseTest { /** * Test default handler that transverses XML and print all visited node. + * + * @throws Exception If any errors occur. */ @Test - public void testDefaultHandler() { - String outputFile = CLASS_DIR + "DefaultHandler.out"; + public void testDefaultHandler() throws Exception { + String outputFile = USER_DIR + "DefaultHandler.out"; String goldFile = GOLDEN_DIR + "DefaultHandlerGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxparser = spf.newSAXParser(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxparser = spf.newSAXParser(); - MyDefaultHandler handler = new MyDefaultHandler(outputFile); - File file = new File(xmlFile); - String Absolutepath = file.getAbsolutePath(); - String newAbsolutePath = Absolutepath; - if (File.separatorChar == '\\') - newAbsolutePath = Absolutepath.replace('\\', '/'); - String uri = "file:///" + newAbsolutePath; - saxparser.parse(uri, handler); - } catch (IOException | ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + MyDefaultHandler handler = new MyDefaultHandler(outputFile); + File file = new File(xmlFile); + String Absolutepath = file.getAbsolutePath(); + String newAbsolutePath = Absolutepath; + if (File.separatorChar == '\\') + newAbsolutePath = Absolutepath.replace('\\', '/'); + saxparser.parse("file:///" + newAbsolutePath, handler); + + assertTrue(compareWithGold(goldFile, outputFile)); + } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,23 +26,19 @@ import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import org.testng.annotations.Test; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,14 +46,16 @@ * ErrorHandler unit test. Set a ErrorHandle to XMLReader. Capture fatal error * events in ErrorHandler. */ -public class EHFatalTest { +public class EHFatalTest extends JAXPFileBaseTest { /** * Error Handler to capture all error events to output file. Verifies the * output file is same as golden file. + * + * @throws Exception If any errors occur. */ @Test - public void testEHFatal() { - String outputFile = CLASS_DIR + "EHFatal.out"; + public void testEHFatal() throws Exception { + String outputFile = USER_DIR + "EHFatal.out"; String goldFile = GOLDEN_DIR + "EHFatalGF.out"; String xmlFile = XML_DIR + "invalid.xml"; @@ -68,25 +66,12 @@ xmlReader.setErrorHandler(eHandler); InputSource is = new InputSource(instream); xmlReader.parse(is); - } catch (IOException | ParserConfigurationException ex) { - failUnexpected(ex); - } catch (SAXException ex) { - System.out.println("This is expected:" + ex); + fail("Parse should throw SAXException"); + } catch (SAXException expected) { + // This is expected. } // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.xml.sax.ptests; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * Simple attributes handler. - */ -public class MyAttrCHandler extends DefaultHandler { - /** - * FileWriter to write string to output file. - */ - private final BufferedWriter bWriter; - - /** - * Initiate FileWriter - * @param fileName output file name. - * @throws IOException - */ - public MyAttrCHandler(String fileName) throws IOException { - bWriter = new BufferedWriter(new FileWriter(fileName)); - } - - /** - * Write element content before start access every element. - * @throws org.xml.sax.SAXException - */ - @Override - public void startElement(String uri, String localName, - String qName, Attributes attributes) throws SAXException { - try { - String string = "uri <" + uri + "> localName <" + localName + - "> qName <" + qName + ">"; - - bWriter.write( string, 0, string.length()); - bWriter.newLine(); - - int length = attributes.getLength(); - string = "length: " + length; - - bWriter.write( string, 0, string.length()); - bWriter.newLine(); - - for (int ind=0; ind < length ; ind++) { - string = "For index = " + ind + "\n"; - string += "getLocalName <" + attributes.getLocalName(ind) - +">" + "\n"; - string += "getQName <" + attributes.getQName(ind) +">" + "\n"; - string += "getType <" + attributes.getType(ind) +">" + "\n"; - string += "getURI <" + attributes.getURI(ind) +">" + "\n"; - string += "getValue <" + attributes.getValue(ind) +">" + "\n"; - - bWriter.write( string, 0, string.length()); - bWriter.newLine(); - - String gotLocalName = attributes.getLocalName(ind); - String gotQName = attributes.getQName(ind); - String gotURI = attributes.getURI(ind); - - string ="Using localName, qname and uri pertaining to index = " - + ind; - bWriter.write( string, 0, string.length()); - bWriter.newLine(); - - string = "getIndex(qName) <" + attributes.getIndex(gotQName) - +">" + "\n"; - string += "getIndex(uri, localName) <" + - attributes.getIndex(gotURI, gotLocalName) +">" + "\n"; - - string += "getType(qName) <" + - attributes.getType(gotQName) +">" + "\n"; - string += "getType(uri, localName) <" + - attributes.getType(gotURI, gotLocalName) +">" + "\n"; - - string += "getValue(qName) <" + - attributes.getValue(gotQName) +">" + "\n"; - string += "getValue(uri, localName) <" + - attributes.getValue(gotURI, gotLocalName) +">" + "\n"; - - bWriter.write( string, 0, string.length()); - bWriter.newLine(); - } - bWriter.newLine(); - } catch(IOException ex){ - throw new SAXException(ex); - } - } - - /** - * Flush the stream and close the file. - * @throws IOException when writing or closing file failed. - */ - public void flushAndClose() throws IOException { - bWriter.flush(); - bWriter.close(); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.xml.sax.ptests; - -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.helpers.LocatorImpl; -import org.xml.sax.Locator; -import org.xml.sax.Attributes; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.FileWriter; -import org.xml.sax.SAXException; - -class MyNSContentHandler extends DefaultHandler { - /** - * Prefix for written string. - */ - private final static String WRITE_ERROR = "bWrite error"; - /** - * FileWriter to write output file. - */ - private final BufferedWriter bWriter; - - /** - * Default locator. - */ - Locator locator = new LocatorImpl(); - - /** - * Initiate FileWrite. - * @param outputFileName file name of output file. - * @throws SAXException when open output file failed. - */ - public MyNSContentHandler(String outputFileName) throws SAXException { - try { - bWriter = new BufferedWriter(new FileWriter(outputFileName)); - } catch (IOException ex) { - throw new SAXException(ex); - } - } - - /** - * Write characters tag along with content of characters when meet - * characters event. - * @throws IOException error happen when writing file. - */ - @Override - public void characters(char[] ch, int start, int length) - throws SAXException { - String s = new String(ch, start, length); - println("characters...length is:" + s.length() + "\n" - + "<" + s + ">"); - } - - /** - * Write endDocument tag then flush the content and close the file when meet - * endDocument event. - * @throws IOException error happen when writing file or closing file. - */ - @Override - public void endDocument() throws SAXException { - try { - println("endDocument..."); - bWriter.flush(); - bWriter.close(); - } catch (IOException ex) { - throw new SAXException(WRITE_ERROR, ex); - } - } - - /** - * Write endElement tag with namespaceURI, localName, qName to the file when - * meet endElement event. - * @throws IOException error happen when writing file. - */ - @Override - public void endElement(String namespaceURI, String localName, String qName) - throws SAXException { - println("endElement...\n" + "namespaceURI: <" + namespaceURI - + "> localName: <" + localName + "> qName: <" + qName + ">"); - } - - /** - * Write endPrefixMapping tag along with prefix to the file when meet - * endPrefixMapping event. - * @throws IOException error happen when writing file. - */ - @Override - public void endPrefixMapping(String prefix) throws SAXException { - println("endPrefixMapping...\n" + "prefix: <" + prefix + ">"); - } - - /** - * Write ignorableWhitespace tag along with white spaces when meet - * ignorableWhitespace event. - * @throws IOException error happen when writing file. - */ - @Override - public void ignorableWhitespace(char[] ch, int start, int length) - throws SAXException { - String s = new String(ch, start, length); - println("ignorableWhitespace...\n" + s - + " ignorable white space string length: " + s.length()); - } - - /** - * Write processingInstruction tag along with target name and target data - * when meet processingInstruction event. - * @throws IOException error happen when writing file. - */ - @Override - public void processingInstruction(String target, String data) - throws SAXException { - println("processingInstruction...target:<" + target - + "> data: <" + data + ">"); - } - - /** - * Write setDocumentLocator tag when meet setDocumentLocator event. - */ - @Override - public void setDocumentLocator(Locator locator) { - try { - this.locator = locator; - println("setDocumentLocator..."); - } catch (SAXException ex) { - System.err.println(WRITE_ERROR + ex); - } - } - - /** - * Write skippedEntity tag along with entity name when meet skippedEntity - * event. - * @throws IOException error happen when writing file. - */ - @Override - public void skippedEntity(String name) throws SAXException { - println("skippedEntity...\n" + "name: <" + name + ">"); - } - - /** - * Write startDocument tag when meet startDocument event. - * @throws IOException error happen when writing file. - */ - @Override - public void startDocument() throws SAXException { - println("startDocument..."); - } - - /** - * Write startElement tag along with namespaceURI, localName, qName, number - * of attributes and line number when meet startElement event. - * @throws IOException error happen when writing file. - */ - @Override - public void startElement(String namespaceURI, String localName, - String qName, Attributes atts) throws SAXException { - println("startElement...\n" + "namespaceURI: <" + namespaceURI - + "> localName: <" + localName + "> qName: <" + qName - + "> Number of Attributes: <" + atts.getLength() - + "> Line# <" + locator.getLineNumber() + ">"); - } - - /** - * Write startPrefixMapping tag along with prefix and uri when meet - * startPrefixMapping event. - * @throws IOException error happen when writing file. - */ - @Override - public void startPrefixMapping(String prefix, String uri) - throws SAXException { - println("startPrefixMapping...\n" + "prefix: <" + prefix - + "> uri: <" + uri + ">"); - } - /** - * Write outString to output file. - * @param outString string to be written. - * @throws SAXException - */ - private void println(String outString) throws SAXException { - try { - bWriter.write( outString, 0, outString.length()); - bWriter.newLine(); - } catch (IOException ex) { - throw new SAXException(WRITE_ERROR, ex); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ package org.xml.sax.ptests; import java.util.Enumeration; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import org.testng.annotations.Test; @@ -31,7 +32,7 @@ /** * Unit test cases for NamespaceSupport API */ -public class NSSupportTest { +public class NSSupportTest extends JAXPBaseTest { /** * Empty prefix name. */ diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.xml.sax.ptests; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPBaseTest; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; +import org.xml.sax.XMLReader; + +/** + * Class containing the test cases for Namespace Table defined at + * http://www.megginson.com/SAX/Java/namespaces.html + */ +public class NSTableTest extends JAXPBaseTest { + private static final String NAMESPACES = + "http://xml.org/sax/features/namespaces"; + private static final String NAMESPACE_PREFIXES = + "http://xml.org/sax/features/namespace-prefixes"; + + /** + * Here namespace processing and namespace-prefixes are enabled. + * The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxParser = spf.newSAXParser(); + + XMLReader xmlReader = saxParser.getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); + + assertTrue(xmlReader.getFeature(NAMESPACES)); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is enabled. This will make namespace-prefixes + * disabled. The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACES)); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled. This will make namespace-prefixes + * enabled. The testcase tests XMLReader for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable03() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACES)); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled, and namespace-prefixes is + * disabled. This will make namespace processing on.The testcase tests + * XMLReader for this. This behavior only apply to crimson, not + * XERCES. + * + * @throws Exception If any errors occur. + */ + @Test + public void xrNSTable04() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing and namespace-prefixes are enabled. + * The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature(NAMESPACE_PREFIXES,true); + assertTrue(spf.getFeature(NAMESPACES)); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is enabled. This will make namespace-prefixes + * disabled. The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + assertTrue(spf.getFeature(NAMESPACES)); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); + } + + /** + * Here namespace processing is disabled. This will make namespace-prefixes + * enabled. The testcase tests SAXParserFactory for this. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.getFeature(NAMESPACES)); + assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); + } + /** + * Here namespace processing is disabled, and namespace-prefixes is + * disabled. This will make namespace processing on.The testcase tests + * SAXParserFactory for this. This behavior only apply to crimson, + * not xerces. + * + * @throws Exception If any errors occur. + */ + @Test + public void spNSTable04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package org.xml.sax.ptests; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; -import org.xml.sax.XMLReader; - -/** - * Class containing the test cases for Namespace Table defined at - * http://www.megginson.com/SAX/Java/namespaces.html - */ -public class NSTableTest01 { - private static final String NAMESPACES = - "http://xml.org/sax/features/namespaces"; - private static final String NAMESPACE_PREFIXES = - "http://xml.org/sax/features/namespace-prefixes"; - - /** - * Here namespace processing and namespace-prefixes are enabled. - * The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - - assertTrue(xmlReader.getFeature(NAMESPACES)); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is enabled. This will make namespace-prefixes - * disabled. The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - - XMLReader xmlReader = saxParser.getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACES)); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - - } - - /** - * Here namespace processing is disabled. This will make namespace-prefixes - * enabled. The testcase tests XMLReader for this. - */ - @Test - public void xrNSTable03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACES)); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is disabled, and namespace-prefixes is - * disabled. This will make namespace processing on.The testcase tests - * XMLReader for this. This behavior only apply to crimson, not - * xerces - */ - @Test - public void xrNSTable04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, false); - - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing and namespace-prefixes are enabled. - * The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature(NAMESPACE_PREFIXES,true); - assertTrue(spf.getFeature(NAMESPACES)); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is enabled. This will make namespace-prefixes - * disabled. The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - assertTrue(spf.getFeature(NAMESPACES)); - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - - /** - * Here namespace processing is disabled. This will make namespace-prefixes - * enabled. The testcase tests SAXParserFactory for this. - */ - @Test - public void spNSTable03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.getFeature(NAMESPACES)); - assertTrue(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } - /** - * Here namespace processing is disabled, and namespace-prefixes is - * disabled. This will make namespace processing on.The testcase tests - * SAXParserFactory for this. This behavior only apply to crimson, - * not xerces. - */ - @Test - public void spNSTable04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(NAMESPACE_PREFIXES, false); - - assertFalse(spf.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXNotRecognizedException - | SAXNotSupportedException ex) { - failUnexpected(ex); - } - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,8 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -35,7 +33,6 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.ParserAdapter; import org.xml.sax.helpers.XMLFilterImpl; @@ -47,7 +44,7 @@ * Unit test cases for ParserAdapter API. By default the only features recognized * are namespaces and namespace-prefixes. */ -public class ParserAdapterTest { +public class ParserAdapterTest extends JAXPFileReadOnlyBaseTest { /** * namespaces feature name. */ @@ -67,10 +64,9 @@ /** * Initiate ParserAdapter. - * @throws ParserConfigurationException - * @throws SAXException + * @throws Exception If any errors occur. */ - ParserAdapterTest() throws ParserConfigurationException, SAXException { + ParserAdapterTest() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); XMLReaderAdapter xmlReaderAdapter = new XMLReaderAdapter(xmlReader); @@ -151,129 +147,111 @@ /** * parserAdapter.getFeature(NAMESPACES) returns true be default. + * + * @exception Exception If any errors occur. */ @Test - public void getFeature01() { - try { - assertTrue(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature01() throws Exception { + assertTrue(parserAdapter.getFeature(NAMESPACES)); } /** * parserAdapter.getFeature(NAMESPACE_PREFIXES) returns true be default. + * + * @exception Exception If any errors occur. */ @Test - public void getFeature02() { - try { - assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature02() throws Exception { + assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * SAXNotRecognizedException thrown when feature name is not known one. - * @throws org.xml.sax.SAXNotRecognizedException expected Exception + * + * @exception Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void getFeature03() throws SAXNotRecognizedException { - try { - parserAdapter.getFeature("no-meaning-feature"); - } catch (SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void getFeature03() throws Exception { + parserAdapter.getFeature("no-meaning-feature"); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature01() { - try { - parserAdapter.setFeature(NAMESPACES, false); - assertFalse(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature01() throws Exception { + parserAdapter.setFeature(NAMESPACES, false); + assertFalse(parserAdapter.getFeature(NAMESPACES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature02() { - try { - parserAdapter.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature02() throws Exception { + parserAdapter.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature03() { - try { - parserAdapter.setFeature(NAMESPACES, true); - assertTrue(parserAdapter.getFeature(NAMESPACES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature03() throws Exception { + parserAdapter.setFeature(NAMESPACES, true); + assertTrue(parserAdapter.getFeature(NAMESPACES)); } /** * Obtain getFeature after it's set returns set value. + * + * @exception Exception If any errors occur. */ @Test - public void setFeature04() { - try { - parserAdapter.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(parserAdapter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXNotRecognizedException | SAXNotSupportedException ex) { - failUnexpected(ex); - } + public void setFeature04() throws Exception { + parserAdapter.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(parserAdapter.getFeature(NAMESPACE_PREFIXES)); } /** * NPE expected when parsing a null object by ParserAdapter. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - parserAdapter.parse((InputSource)null); - } catch (IOException | SAXException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + parserAdapter.parse((InputSource)null); } /** * SAXException expected when parsing a wrong-formatter XML with ParserAdapter. - * @throws org.xml.sax.SAXException + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class) - public void parse02() throws SAXException { + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class) + public void parse02() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { InputSource is = new InputSource(fis); parserAdapter.parse(is); - } catch (IOException ex) { - failUnexpected(ex); } } /** * Parse a well-formatter XML with ParserAdapter. + * + * @throws Exception If any errors occur. */ - @Test - public void parse03() { + @Test(groups = {"readLocalFiles"}) + public void parse03() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "correct.xml")) { InputSource is = new InputSource(fis); parserAdapter.parse(is); - } catch (IOException | SAXException ex) { - failUnexpected(ex); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,21 +26,16 @@ import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -48,12 +43,14 @@ * Entity resolver should be invoked in XML parse. This test verifies parsing * process by checking the output with golden file. */ -public class ResolverTest { +public class ResolverTest extends JAXPFileBaseTest { /** * Unit test for entityResolver setter. + * + * @throws Exception If any errors occur. */ - public void testResolver() { - String outputFile = CLASS_DIR + "EntityResolver.out"; + public void testResolver() throws Exception { + String outputFile = USER_DIR + "EntityResolver.out"; String goldFile = GOLDEN_DIR + "EntityResolverGF.out"; String xmlFile = XML_DIR + "publish.xml"; @@ -64,23 +61,8 @@ xmlReader.setEntityResolver(eResolver); InputSource is = new InputSource(instream); xmlReader.parse(is); - } catch(IOException | SAXException | ParserConfigurationException ex ) { - failUnexpected(ex); } - // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,12 @@ package org.xml.sax.ptests; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; -import org.xml.sax.SAXException; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -44,91 +36,64 @@ * This class contains the testcases to test SAXParser with regard to * Namespace Table defined at http://www.megginson.com/SAX/Java/namespaces.html */ -public class SAXParserNSTableTest { +public class SAXParserNSTableTest extends JAXPFileBaseTest { /** * namespace processing is enabled. namespace-prefix is also is enabled. * So it is a True-True combination. - * The test is to test SAXParser with these conditions + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ @Test - public void testWithTrueTrue() { - String outputFile = CLASS_DIR + "SPNSTableTT.out"; + public void testWithTrueTrue() throws Exception { + String outputFile = USER_DIR + "SPNSTableTT.out"; String goldFile = GOLDEN_DIR + "NSTableTTGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setFeature("http://xml.org/sax/features/namespace-prefixes", - true); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); + } + assertTrue(compareWithGold(goldFile, outputFile)); - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } } /** * namespace processing is enabled. Hence namespace-prefix is - * expected to be automaically off. So it is a True-False combination. - * The test is to test SAXParser with these conditions + * expected to be automatically off. So it is a True-False combination. + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueFalse() { - String outputFile = CLASS_DIR + "SPNSTableTF.out"; + public void testWithTrueFalse() throws Exception { + String outputFile = USER_DIR + "SPNSTableTF.out"; String goldFile = GOLDEN_DIR + "NSTableTFGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * namespace processing is not enabled. Hence namespace-prefix is - * expected to be automaically on. So it is a False-True combination. - * The test is to test SAXParser with these conditions + * expected to be automatically on. So it is a False-True combination. + * The test is to test SAXParser with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithFalseTrue() { - String outputFile = CLASS_DIR + "SPNSTableFT.out"; + public void testWithFalseTrue() throws Exception { + String outputFile = USER_DIR + "SPNSTableFT.out"; String goldFile = GOLDEN_DIR + "NSTableFTGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - saxParser.parse(new File(xmlFile), new MyNSContentHandler(outputFile)); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + try (MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + spf.newSAXParser().parse(new File(xmlFile), handler); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,14 +26,10 @@ import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.Attributes; import org.xml.sax.InputSource; @@ -42,7 +38,6 @@ import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -50,45 +45,34 @@ * Set parent of XMLFilter to XMLReader. Parsing on XML file will invoke XMLFilter * to write to output file. Test verifies output is same as the golden file. */ -public class XMLFilterCBTest { - public void testXMLFilterCB() { - String outputFile = CLASS_DIR + "XMLFilter.out"; +public class XMLFilterCBTest extends JAXPFileBaseTest { + /** + * Test XMLFilter working with XML reader. + * + * @throws Exception If any errors occur. + */ + public void testXMLFilterCB() throws Exception { + String outputFile = USER_DIR + "XMLFilter.out"; String goldFile = GOLDEN_DIR + "XMLFilterGF.out"; String xmlFile = XML_DIR + "namespace1.xml"; - try (FileInputStream fis = new FileInputStream(xmlFile)){ + try (FileInputStream fis = new FileInputStream(xmlFile); + MyXMLFilter myXmlFilter = new MyXMLFilter(outputFile)){ SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - MyXMLFilter myXmlFilter = new MyXMLFilter(outputFile); myXmlFilter.setParent(xmlReader); - InputSource is = new InputSource(fis); - myXmlFilter.parse(is); - } catch( SAXException | IOException | ParserConfigurationException ex) { - failUnexpected(ex); + myXmlFilter.parse(new InputSource(fis)); } // Need close the output file before we compare it with golden file. - try { - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (IOException ex) { - failUnexpected(ex); - } finally { - try { - Path outputPath = Paths.get(outputFile); - if(Files.exists(outputPath)) - Files.delete(outputPath); - } catch (IOException ex) { - failCleanup(ex, outputFile); - } - } + assertTrue(compareWithGold(goldFile, outputFile)); } } /** * Writer XMLFiler which write all tags to output file when event happens. */ -class MyXMLFilter extends XMLFilterImpl{ +class MyXMLFilter extends XMLFilterImpl implements AutoCloseable { /** * FileWriter to write string to output file. */ @@ -278,4 +262,14 @@ throw new SAXException(ex); } } + + /** + * Close writer handler. + * @throws IOException if any I/O error when close writer handler. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,18 +23,14 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -42,7 +38,7 @@ /** * Unit test for XMLFilter. */ -public class XMLFilterTest { +public class XMLFilterTest extends JAXPFileReadOnlyBaseTest { /** * name spaces constant. */ @@ -129,139 +125,114 @@ /** * By default true is expected get namespaces feature. - * @throws SAXException + * + * @throws Exception If any errors occur. */ @Test - public void getFeature01() throws SAXException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void getFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - assertTrue(xmlFilter.getFeature(NAMESPACES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(xmlReader); + assertTrue(xmlFilter.getFeature(NAMESPACES)); } /** * By default false is expected get namespaces-prefix feature. + * + * @throws Exception If any errors occur. */ @Test - public void getFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void getFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); } /** * SAXNotRecognizedException is expected when get a feature by an invalid * feature name. - * @throws org.xml.sax.SAXNotRecognizedException If the feature - * value can't be assigned or retrieved from the parent. - * @throws org.xml.sax.SAXNotSupportedException When the - * parent recognizes the feature name but - * cannot determine its value at this time. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void getFeature03() throws SAXNotRecognizedException, - SAXNotSupportedException { + public void getFeature03() throws Exception { new XMLFilterImpl().getFeature("no-meaning-feature"); } /** * Set namespaces feature to a value to XMLFilter. it's expected same when * obtain it again. + * + * @throws Exception If any errors occur. */ @Test - public void setFeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void setFeature01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - xmlFilter.setFeature(NAMESPACES, false); - assertFalse(xmlFilter.getFeature(NAMESPACES)); - xmlFilter.setFeature(NAMESPACES, true); - assertTrue(xmlFilter.getFeature(NAMESPACES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + xmlFilter.setFeature(NAMESPACES, false); + assertFalse(xmlFilter.getFeature(NAMESPACES)); + xmlFilter.setFeature(NAMESPACES, true); + assertTrue(xmlFilter.getFeature(NAMESPACES)); } /** * Set namespaces-prefix feature to a value to XMLFilter. it's expected same * when obtain it again. + * + * @throws Exception If any errors occur. */ @Test - public void setFeature02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void setFeature02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlFilter.setParent(xmlReader); - xmlFilter.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - xmlFilter.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(xmlFilter.getFeature(NAMESPACE_PREFIXES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlFilter.setParent(spf.newSAXParser().getXMLReader()); + xmlFilter.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlFilter.getFeature(NAMESPACE_PREFIXES)); + xmlFilter.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(xmlFilter.getFeature(NAMESPACE_PREFIXES)); } /** * NullPointerException is expected when parse a null InputSource. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - new XMLFilterImpl().parse((InputSource)null); - } catch (IOException | SAXException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + new XMLFilterImpl().parse((InputSource)null); } /** * SAXException is expected when parsing a invalid formatted XML file. - * @throws org.xml.sax.SAXException when parse a incorrect formatted XML - * file. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void parse02() throws SAXException { - XMLFilterImpl xmlFilter = new XMLFilterImpl(); + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void parse02() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { - InputSource is = new InputSource(fis); - xmlFilter.parse(is); - } catch (IOException ex) { - failUnexpected(ex); + new XMLFilterImpl().parse(new InputSource(fis)); } } /** * No exception when parse a normal XML file. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = NullPointerException.class) - public void parse03() { - XMLFilterImpl xmlFilter = new XMLFilterImpl(); + @Test(groups = {"readLocalFiles"}, expectedExceptions = NullPointerException.class) + public void parse03() throws Exception { try(FileInputStream fis = new FileInputStream(XML_DIR + "correct2.xml")) { - InputSource is = new InputSource(fis); - xmlFilter.parse(is); - } catch (IOException | SAXException ex) { - failUnexpected(ex); + new XMLFilterImpl().parse(new InputSource(fis)); } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; +import java.io.FilePermission; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; @@ -40,7 +39,7 @@ /** * Class containing the test cases for XMLReaderAdapter API */ -public class XMLReaderAdapterTest { +public class XMLReaderAdapterTest extends JAXPBaseTest { /** * http://xml.org/sax/features/namespace-prefixes property name. */ @@ -58,60 +57,51 @@ } /** - * To test the constructor that uses XMLReader + * To test the constructor that uses XMLReader. + * + * @throws Exception If any errors occur. */ @Test - public void constructor02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - - assertNotNull(new XMLReaderAdapter(xmlReader)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void constructor02() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + assertNotNull(new XMLReaderAdapter(xmlReader)); } /** * To test the parse method. The specification says that this method * will throw an exception if the embedded XMLReader does not support * the http://xml.org/sax/features/namespace-prefixes property. + * + * @throws Exception If any errors occur. */ @Test - public void nsfeature01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { - xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); - } - - assertTrue(xmlReader.getFeature(NM_PREFIXES_PROPERTY)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + public void nsfeature01() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { + xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); } + assertTrue(xmlReader.getFeature(NM_PREFIXES_PROPERTY)); } /** * To test the parse method. The specification says that this method * will throw an exception if the embedded XMLReader does not support * the http://xml.org/sax/features/namespace-prefixes property. + * + * @throws Exception If any errors occur. */ @Test - public void parse01() { + public void parse01() throws Exception { + setPermissions(new FilePermission(XML_DIR + "/-", "read")); try (FileInputStream fis = new FileInputStream(XML_DIR + "namespace1.xml")) { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); if (!xmlReader.getFeature(NM_PREFIXES_PROPERTY)) { xmlReader.setFeature(NM_PREFIXES_PROPERTY, true); } XMLReaderAdapter xmlRA = new XMLReaderAdapter(xmlReader); - - InputSource is = new InputSource(fis); xmlRA.setDocumentHandler(new HandlerBase()); - xmlRA.parse(is); - } catch (IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + xmlRA.parse(new InputSource(fis)); } + setPermissions(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ package org.xml.sax.ptests; +import jaxp.library.JAXPBaseTest; import static org.testng.Assert.assertNotNull; import org.testng.annotations.Test; import org.xml.sax.SAXException; @@ -30,7 +31,7 @@ /** * Unit test for XMLReaderFactory.createXMLReader API. */ -public class XMLReaderFactoryTest { +public class XMLReaderFactoryTest extends JAXPBaseTest { /** * No exception expected when create XMLReader by default. * @throws org.xml.sax.SAXException when xml reader creation failed. @@ -48,12 +49,7 @@ */ @Test public void createReader02() throws SAXException { - //Disable this test because this is only work for apache implementation. - /*System.setProperty("org.xml.sax.driver", - "org.apache.xerces.parsers.SAXParser"); - assertNotNull(XMLReaderFactory. - createXMLReader("org.apache.xerces.parsers.SAXParser"));*/ - System.setProperty("org.xml.sax.driver", + setSystemProperty("org.xml.sax.driver", "com.sun.org.apache.xerces.internal.parsers.SAXParser"); assertNotNull(XMLReaderFactory. createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser")); diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,17 +23,14 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareWithGold; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertTrue; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import static org.xml.sax.ptests.SAXTestConst.CLASS_DIR; import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR; import static org.xml.sax.ptests.SAXTestConst.XML_DIR; @@ -41,7 +38,7 @@ * Namespace Table defined at * http://www.megginson.com/SAX/Java/namespaces.html */ -public class XMLReaderNSTableTest { +public class XMLReaderNSTableTest extends JAXPFileBaseTest { /** * XML file that used to be parsed. */ @@ -55,71 +52,70 @@ /** * namespace processing is enabled. namespace-prefix is also is enabled. * So it is a True-True combination. - * The test is to test XMLReader with these conditions + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueTrue() { - String outputFile = CLASS_DIR + "XRNSTableTT.out"; + public void testWithTrueTrue() throws Exception { + String outputFile = USER_DIR + "XRNSTableTT.out"; String goldFile = GOLDEN_DIR + "NSTableTTGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile);) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * Namespace processing is enabled. Hence namespace-prefix is - * expected to be automaically off. So it is a True-False combination. - * The test is to test XMLReader with these conditions + * expected to be automatically off. So it is a True-False combination. + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithTrueFalse() { - String outputFile = CLASS_DIR + "XRNSTableTF.out"; + public void testWithTrueFalse() throws Exception { + String outputFile = USER_DIR + "XRNSTableTF.out"; String goldFile = GOLDEN_DIR + "NSTableTFGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser saxParser = spf.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } /** * namespace processing is not enabled. Hence namespace-prefix is * expected to be automaically on. So it is a False-True combination. - * The test is to test XMLReader with these conditions + * The test is to test XMLReader with these conditions. + * + * @throws Exception If any errors occur. */ - public void testWithFalseTrue() { - String outputFile = CLASS_DIR + "XRNSTableFT.out"; + public void testWithFalseTrue()throws Exception { + String outputFile = USER_DIR + "XRNSTableFT.out"; String goldFile = GOLDEN_DIR + "NSTableFTGF.out"; - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - - xmlReader.setContentHandler(new MyNSContentHandler(outputFile)); - xmlReader.parse(new InputSource(new FileInputStream(xmlFile))); - assertTrue(compareWithGold(goldFile, outputFile)); - } catch (ParserConfigurationException | SAXException | IOException ex) { - failUnexpected(ex); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + try (FileInputStream fis = new FileInputStream(xmlFile); + MyNSContentHandler handler = new MyNSContentHandler(outputFile)) { + xmlReader.setContentHandler(handler); + xmlReader.parse(new InputSource(fis)); } + assertTrue(compareWithGold(goldFile, outputFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java --- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,9 @@ package org.xml.sax.ptests; import java.io.FileInputStream; -import java.io.IOException; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; -import static jaxp.library.JAXPTestUtilities.failUnexpected; +import jaxp.library.JAXPFileReadOnlyBaseTest; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @@ -45,42 +44,43 @@ /** * Class containing the test cases for SAXParser API */ -public class XMLReaderTest { +public class XMLReaderTest extends JAXPFileReadOnlyBaseTest { + /** * XML namespaces. */ - private static final String NAMESPACES = - "http://xml.org/sax/features/namespaces"; + private static final String NAMESPACES + = "http://xml.org/sax/features/namespaces"; /** * XML namespaces prefixes. */ - private static final String NAMESPACE_PREFIXES = - "http://xml.org/sax/features/namespace-prefixes"; + private static final String NAMESPACE_PREFIXES + = "http://xml.org/sax/features/namespace-prefixes"; /** * A string intern name. */ - private static final String STRING_INTERNING = - "http://xml.org/sax/features/string-interning"; + private static final String STRING_INTERNING + = "http://xml.org/sax/features/string-interning"; /** * Validation name. */ - private static final String VALIDATION = - "http://xml.org/sax/features/validation"; + private static final String VALIDATION + = "http://xml.org/sax/features/validation"; /** * A general external entities name */ - private static final String EXTERNAL_G_ENTITIES = - "http://xml.org/sax/features/external-general-entities"; + private static final String EXTERNAL_G_ENTITIES + = "http://xml.org/sax/features/external-general-entities"; /** * A external parameter entities name */ - private static final String EXTERNAL_P_ENTITIES = - "http://xml.org/sax/features/external-parameter-entities"; + private static final String EXTERNAL_P_ENTITIES + = "http://xml.org/sax/features/external-parameter-entities"; /** * XML DOM node name. @@ -95,526 +95,444 @@ /** * Declare handler name */ - private static final String DECL_HANDLER = - "http://xml.org/sax/properties/declaration-handler"; + private static final String DECL_HANDLER + = "http://xml.org/sax/properties/declaration-handler"; /** * Lexical handler name */ - private static final String LEXICAL_HANDLER = - "http://xml.org/sax/properties/lexical-handler"; + private static final String LEXICAL_HANDLER + = "http://xml.org/sax/properties/lexical-handler"; /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespaces feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespaces feature names. This test case is + * to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespaces feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespaces feature names. This test case is + * to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACES)); } /** * Obtain http://xml.org/sax/features/namespaces feature name after it's * just set. Expect it's same as set value. + * + * @throws Exception If any errors occur. */ @Test - public void featureNS03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(NAMESPACES, true); - assertTrue(xmlReader.getFeature(NAMESPACES)); - xmlReader.setFeature(NAMESPACES, false); - assertFalse(xmlReader.getFeature(NAMESPACES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNS03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACES, true); + assertTrue(xmlReader.getFeature(NAMESPACES)); + xmlReader.setFeature(NAMESPACES, false); + assertFalse(xmlReader.getFeature(NAMESPACES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespace-prefixes feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespace-prefixes feature names. This test + * case is to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * According to the SAX2 specs, All XMLReaders are required to recognize the - * http://xml.org/sax/features/namespace-prefixes feature names. - * This test case is to test this. + * http://xml.org/sax/features/namespace-prefixes feature names. This test + * case is to test this. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * Obtain http://xml.org/sax/features/namespaces-prefixes feature name after * it's just set. Expect it's same as set value. + * + * @throws Exception If any errors occur. */ @Test - public void featureNSP03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(NAMESPACE_PREFIXES, true); - assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); - xmlReader.setFeature(NAMESPACE_PREFIXES, false); - assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); - } catch (ParserConfigurationException | SAXException ex) { - failUnexpected(ex); - } + public void featureNSP03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(NAMESPACE_PREFIXES, true); + assertTrue(xmlReader.getFeature(NAMESPACE_PREFIXES)); + xmlReader.setFeature(NAMESPACE_PREFIXES, false); + assertFalse(xmlReader.getFeature(NAMESPACE_PREFIXES)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureSI01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(STRING_INTERNING)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureSI01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(STRING_INTERNING)); } /** * getFeature with validation feature name returns the value that * setValidation set. + * + * @throws Exception If any errors occur. */ @Test - public void featureV01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - assertFalse(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); - spf.setValidating(true); - assertTrue(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureV01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + assertFalse(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); + spf.setValidating(true); + assertTrue(spf.newSAXParser().getXMLReader().getFeature(VALIDATION)); } /** - * getFeature returns the value that a feature has been preset as when + * getFeature returns the value that a feature has been preset as when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureV02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + public void featureV02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(VALIDATION, true); - assertTrue(xmlReader.getFeature(VALIDATION)); - - xmlReader.setFeature(VALIDATION, false); - assertFalse(xmlReader.getFeature(VALIDATION)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + xmlReader.setFeature(VALIDATION, true); + assertTrue(xmlReader.getFeature(VALIDATION)); + xmlReader.setFeature(VALIDATION, false); + assertFalse(xmlReader.getFeature(VALIDATION)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEGE01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEGE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); } /** - * getFeature returns false if a feature has been preset as false when + * getFeature returns false if a feature has been preset as false when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEGE02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(EXTERNAL_G_ENTITIES, false); - assertFalse(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEGE02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(EXTERNAL_G_ENTITIES, false); + assertFalse(xmlReader.getFeature(EXTERNAL_G_ENTITIES)); } /** * getFeature returns true if a feature has not been preset when namespace * awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEPE01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertTrue(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEPE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertTrue(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); } /** - * getFeature returns false if a feature has been preset as false when + * getFeature returns false if a feature has been preset as false when * namespace awareness is set. + * + * @throws Exception If any errors occur. */ @Test - public void featureEPE02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setFeature(EXTERNAL_P_ENTITIES, false); - assertFalse(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureEPE02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setFeature(EXTERNAL_P_ENTITIES, false); + assertFalse(xmlReader.getFeature(EXTERNAL_P_ENTITIES)); } /** * getFeature with a unknown feature name throws SAXNotRecognizedException. - * @throws SAXNotRecognizedException If the feature value can't be assigned - * or retrieved. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotRecognizedException.class) - public void featureNE01() throws SAXNotRecognizedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - boolean noMeaningFeature = xmlReader.getFeature("no-meaning-feature"); - } catch(SAXNotRecognizedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void featureNE01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().getFeature("no-meaning-feature"); } /** * No exception expected when set entity resolver as simple entity resolver. + * + * @throws Exception If any errors occur. */ @Test - public void entity01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setEntityResolver(xmlFilter); - assertNotNull(xmlReader.getEntityResolver()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void entity01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setEntityResolver(xmlFilter); + assertEquals(xmlReader.getEntityResolver(), xmlFilter); } /** * No NPE expected when set entity resolver as null. + * + * @throws Exception If any errors occur. */ @Test - public void entity02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setEntityResolver(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void entity02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setEntityResolver(null); } /** * No exception expected when set DTD handler as simple DTD handler. + * + * @throws Exception If any errors occur. */ @Test - public void dtdhandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setDTDHandler(xmlFilter); - assertNotNull(xmlReader.getDTDHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void dtdhandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setDTDHandler(xmlFilter); + assertEquals(xmlReader.getDTDHandler(), xmlFilter); } /** * No NPE expected when set DTD handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void dtdhandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setDTDHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void dtdhandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setDTDHandler(null); } /** * No exception expected when set content handler as simple content handler. + * + * @throws Exception If any errors occur. */ @Test - public void contenthandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - XMLFilterImpl xmlFilter = new XMLFilterImpl(); - xmlReader.setContentHandler(xmlFilter); - assertNotNull(xmlReader.getContentHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void contenthandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + XMLFilterImpl xmlFilter = new XMLFilterImpl(); + xmlReader.setContentHandler(xmlFilter); + assertEquals(xmlReader.getContentHandler(), xmlFilter); } /** * No NPE expected when set content handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void contenthandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setContentHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void contenthandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().setContentHandler(null); } /** * No exception expected when set content handler as simple error handler. + * + * @throws Exception If any errors occur. */ @Test - public void errorhandler01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setErrorHandler(new XMLFilterImpl()); - assertNotNull(xmlReader.getErrorHandler()); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void errorhandler01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setErrorHandler(new XMLFilterImpl()); + assertNotNull(xmlReader.getErrorHandler()); } /** * No NPE expected when set error handler as null. + * + * @throws Exception If any errors occur. */ @Test - public void errorhandler02() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.setErrorHandler(null); - } catch (SAXException | ParserConfigurationException ex) { - failUnexpected(ex); - } + public void errorhandler02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.setErrorHandler(null); } /** * Parse a null input source throw NPE. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = NullPointerException.class) - public void parse01() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.parse((InputSource)null); - } catch (SAXException | ParserConfigurationException | IOException ex) { - failUnexpected(ex); - } + public void parse01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.newSAXParser().getXMLReader().parse((InputSource) null); } /** * Unit test for parse a error-formatted file. SAXException is expected. - * @throws org.xml.sax.SAXException parsing failed. + * + * @throws Exception If any errors occur. */ - @Test(expectedExceptions = SAXException.class) - public void parse02() throws SAXException { - try (FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")){ + @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXException.class) + public void parse02() throws Exception { + try (FileInputStream fis = new FileInputStream(XML_DIR + "invalid.xml")) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - InputSource is = new InputSource(fis); - xmlReader.parse(is); - } catch (ParserConfigurationException | IOException ex) { - failUnexpected(ex); + spf.newSAXParser().getXMLReader().parse(new InputSource(fis)); } } /** * Unit test for parse a well-formatted file. No exception is expected. + * + * @throws Exception If any errors occur. */ - @Test - public void parse03(){ + @Test(groups = {"readLocalFiles"}) + public void parse03() throws Exception { try (FileInputStream fis = new FileInputStream(XML_DIR + "correct2.xml")) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - InputSource is = new InputSource(fis); - xmlReader.parse(is); - } catch (IOException | SAXException | ParserConfigurationException ex) { - failUnexpected(ex); + spf.newSAXParser().getXMLReader().parse(new InputSource(fis)); } } /** - * Modified by IBM - * Xerces does not support this feature and it is not mandatory - * @throws org.xml.sax.SAXNotSupportedException + * Modified by IBM Xerces does not support this feature and it is not + * mandatory. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotSupportedException.class) - public void xrProperty01() throws SAXNotSupportedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - xmlReader.getProperty(XML_STRING); - } catch(SAXNotSupportedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty01() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + xmlReader.getProperty(XML_STRING); } /** * SAXNotSupportedException thrown if property name is known but no value * assigned to this property. - * @throws org.xml.sax.SAXNotSupportedException when XMLReader recognizes - * the property name but cannot determine its value at this time. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXNotSupportedException.class) - public void xrProperty02() throws SAXNotSupportedException { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(DOM_NODE)); - } catch (SAXNotSupportedException ex) { - throw ex; - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty02() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(DOM_NODE)); } - /** * XMLReader.getProperty returns null if LEXICAL_HANDLER wasn't set. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty03() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(LEXICAL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty03() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(LEXICAL_HANDLER)); } /** * XMLReader.getProperty returns null if DECL_HANDLER wasn't set. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty04() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - assertNull(xmlReader.getProperty(DECL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty04() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + assertNull(xmlReader.getProperty(DECL_HANDLER)); } /** * XMLReader.setProperty/getProperty for LEXICAL_HANDLER unit test. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty05() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); - xmlReader.setProperty(LEXICAL_HANDLER, myLexicalHandler); - assertNotNull(xmlReader.getProperty(LEXICAL_HANDLER)); - } catch (SAXException | ParserConfigurationException ex){ - failUnexpected(ex); - } + public void xrProperty05() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + MyLexicalHandler myLexicalHandler = new MyLexicalHandler(); + xmlReader.setProperty(LEXICAL_HANDLER, myLexicalHandler); + assertNotNull(xmlReader.getProperty(LEXICAL_HANDLER)); } /** * XMLReader.setProperty/getProperty for DECL_HANDLER unit test. + * + * @throws Exception If any errors occur. */ @Test - public void xrProperty06() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - XMLReader xmlReader = spf.newSAXParser().getXMLReader(); - MyDeclHandler myDeclHandler = new MyDeclHandler(); - xmlReader.setProperty(DECL_HANDLER, myDeclHandler); - assertNotNull(xmlReader.getProperty(DECL_HANDLER)); - } catch (ParserConfigurationException | SAXException ex){ - failUnexpected(ex); - } + public void xrProperty06() throws Exception { + SAXParserFactory spf = SAXParserFactory.newInstance(); + XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + MyDeclHandler myDeclHandler = new MyDeclHandler(); + xmlReader.setProperty(DECL_HANDLER, myDeclHandler); + assertNotNull(xmlReader.getProperty(DECL_HANDLER)); } } @@ -622,6 +540,7 @@ * Simple LexicalHandler that skips every lexical event. */ class MyLexicalHandler implements LexicalHandler { + /** * Report an XML comment anywhere in the document. * @@ -667,8 +586,10 @@ * Report the start of DTD declarations, if any. * * @param name The document type name. - * @param publicId The declared public identifier for the external DTD subset. - * @param systemId The declared system identifier for the external DTD subset. + * @param publicId The declared public identifier for the external DTD + * subset. + * @param systemId The declared system identifier for the external DTD + * subset. */ @Override public void startDTD(String name, String publicId, String systemId) { @@ -688,16 +609,17 @@ * Simple DeclHandler that skips every DTD declaration event. */ class MyDeclHandler implements DeclHandler { + /** * Report an attribute type declaration. + * * @param eName The name of the associated element. * @param aName The name of the attribute. * @param type A string representing the attribute type. * @param mode A string representing the attribute defaulting mode - * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if - * none of these applies. - * @param value A string representing the attribute's default value, - * or null if there is none. + * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if none of these applies. + * @param value A string representing the attribute's default value, or null + * if there is none. */ @Override public void attributeDecl(String eName, String aName, String type, @@ -706,6 +628,7 @@ /** * Report an element type declaration. + * * @param name The element type name. * @param model The content model as a normalized string. */ @@ -715,10 +638,11 @@ /** * Report a parsed external entity declaration. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%'. - * @param publicId The entity's public identifier, or null if none - * was given. + * + * @param name The name of the entity. If it is a parameter entity, the name + * will begin with '%'. + * @param publicId The entity's public identifier, or null if none was + * given. * @param systemId The entity's system identifier. */ @Override @@ -728,8 +652,9 @@ /** * Report an internal entity declaration. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%'. + * + * @param name The name of the entity. If it is a parameter entity, the name + * will begin with '%'. * @param value The replacement text of the entity. */ @Override diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,23 +27,18 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; - import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.nio.file.Paths; import java.util.GregorianCalendar; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; - -import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.dom.DOMResult; @@ -51,8 +46,8 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; +import jaxp.library.JAXPFileReadOnlyBaseTest; import static jaxp.library.JAXPTestUtilities.bomStream; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import org.testng.annotations.Test; import org.w3c.dom.Attr; import org.w3c.dom.DOMConfiguration; @@ -63,173 +58,160 @@ import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; -import org.xml.sax.SAXException; import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; import static test.auctionportal.HiBidConstants.XML_DIR; /** * This is the user controller class for the Auction portal HiBid.com. */ -public class AuctionController { +public class AuctionController extends JAXPFileReadOnlyBaseTest { /** * Check for DOMErrorHandler handling DOMError. Before fix of bug 4890927 * DOMConfiguration.setParameter("well-formed",true) throws an exception. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateNewItem2Sell() { + @Test(groups = {"readLocalFiles"}) + public void testCreateNewItem2Sell() throws Exception { String xmlFile = XML_DIR + "novelsInvalid.xml"; - try { - Document document = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().parse(xmlFile); + Document document = DocumentBuilderFactory.newInstance() + .newDocumentBuilder().parse(xmlFile); - document.getDomConfig().setParameter("well-formed", true); + document.getDomConfig().setParameter("well-formed", true); - DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); - DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); - MyDOMOutput domOutput = new MyDOMOutput(); - domOutput.setByteStream(System.out); - LSSerializer writer = impl.createLSSerializer(); - writer.write(document, domOutput); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + MyDOMOutput domOutput = new MyDOMOutput(); + domOutput.setByteStream(System.out); + LSSerializer writer = impl.createLSSerializer(); + writer.write(document, domOutput); } /** * Check for DOMErrorHandler handling DOMError. Before fix of bug 4896132 * test throws DOM Level 1 node error. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateNewItem2SellRetry() { + @Test(groups = {"readLocalFiles"}) + public void testCreateNewItem2SellRetry() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); - DOMConfiguration domConfig = document.getDomConfig(); - MyDOMErrorHandler errHandler = new MyDOMErrorHandler(); - domConfig.setParameter("error-handler", errHandler); + DOMConfiguration domConfig = document.getDomConfig(); + MyDOMErrorHandler errHandler = new MyDOMErrorHandler(); + domConfig.setParameter("error-handler", errHandler); - DOMImplementationLS impl = - (DOMImplementationLS) DOMImplementationRegistry.newInstance() - .getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); - MyDOMOutput domoutput = new MyDOMOutput(); - - domoutput.setByteStream(System.out); - writer.write(document, domoutput); + DOMImplementationLS impl = + (DOMImplementationLS) DOMImplementationRegistry.newInstance() + .getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + MyDOMOutput domoutput = new MyDOMOutput(); - document.normalizeDocument(); - writer.write(document, domoutput); - assertFalse(errHandler.isError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + domoutput.setByteStream(System.out); + writer.write(document, domoutput); + + document.normalizeDocument(); + writer.write(document, domoutput); + assertFalse(errHandler.isError()); } /** * Check if setting the attribute to be of type ID works. This will affect * the Attr.isID method according to the spec. + * + * @throws Exception If any errors occur. */ - @Test - public void testCreateID() { + @Test(groups = {"readLocalFiles"}) + public void testCreateID() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); - Element account = (Element)document - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + Document document = dbf.newDocumentBuilder().parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - account.setIdAttributeNS(PORTAL_ACCOUNT_NS, "accountID", true); - Attr aID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); - assertTrue(aID.isId()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + account.setIdAttributeNS(PORTAL_ACCOUNT_NS, "accountID", true); + Attr aID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(aID.isId()); } /** * Check the user data on the node. + * + * @throws Exception If any errors occur. */ - @Test - public void testCheckingUserData() { + @Test(groups = {"readLocalFiles"}) + public void testCheckingUserData() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(xmlFile); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + Document document = docBuilder.parse(xmlFile); - Element account = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - assertEquals(account.getNodeName(), "acc:Account"); - Element firstName = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); - assertEquals(firstName.getNodeName(), "FirstName"); + Element account = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + assertEquals(account.getNodeName(), "acc:Account"); + Element firstName = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + assertEquals(firstName.getNodeName(), "FirstName"); - Document doc1 = docBuilder.newDocument(); - Element someName = doc1.createElement("newelem"); + Document doc1 = docBuilder.newDocument(); + Element someName = doc1.createElement("newelem"); - someName.setUserData("mykey", "dd", - (operation, key, data, src, dst) -> { - System.err.println("In UserDataHandler" + key); - System.out.println("In UserDataHandler"); - }); - Element impAccount = (Element)document.importNode(someName, true); - assertEquals(impAccount.getNodeName(), "newelem"); - document.normalizeDocument(); - String data = (someName.getUserData("mykey")).toString(); - assertEquals(data, "dd"); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + someName.setUserData("mykey", "dd", + (operation, key, data, src, dst) -> { + System.err.println("In UserDataHandler" + key); + System.out.println("In UserDataHandler"); + }); + Element impAccount = (Element)document.importNode(someName, true); + assertEquals(impAccount.getNodeName(), "newelem"); + document.normalizeDocument(); + String data = (someName.getUserData("mykey")).toString(); + assertEquals(data, "dd"); } /** * Check the UTF-16 XMLEncoding xml file. + * + * @throws Exception If any errors occur. * @see movies.xml */ - @Test - public void testCheckingEncoding() { + @Test(groups = {"readLocalFiles"}) + public void testCheckingEncoding() throws Exception { // Note since movies.xml is UTF-16 encoding. We're not using stanard XML // file suffix. String xmlFile = XML_DIR + "movies.xml.data"; - //try (FileInputStream is = new FileInputStream(xmlFile)) { - try { + try (InputStream source = bomStream("UTF-16", xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); - InputStream source = bomStream("UTF-16", xmlFile); Document document = dbf.newDocumentBuilder().parse(source); assertEquals(document.getXmlEncoding(), "UTF-16"); assertEquals(document.getXmlStandalone(), true); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); } } /** * Check validation API features. A schema which is including in Bug 4909119 * used to be testing for the functionalities. + * + * @throws Exception If any errors occur. * @see userDetails.xsd */ - @Test - public void testGetOwnerInfo() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerInfo() throws Exception { String schemaFile = XML_DIR + "userDetails.xsd"; String xmlFile = XML_DIR + "userDetails.xml"; - try { + try(FileInputStream fis = new FileInputStream(xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); @@ -244,27 +226,27 @@ DocumentBuilder docBuilder = dbf.newDocumentBuilder(); docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(new FileInputStream(xmlFile)); + Document document = docBuilder.parse(fis); DOMResult dResult = new DOMResult(); DOMSource domSource = new DOMSource(document); validator.validate(domSource, dResult); assertFalse(eh.isAnyError()); - } catch (SAXException | ParserConfigurationException | IOException e) { - failUnexpected(e); } } /** * Check grammar caching with imported schemas. + * + * @throws Exception If any errors occur. * @see coins.xsd * @see coinsImportMe.xsd */ - @Test - public void testGetOwnerItemList() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerItemList() throws Exception { String xsdFile = XML_DIR + "coins.xsd"; String xmlFile = XML_DIR + "coins.xml"; - try { + try(FileInputStream fis = new FileInputStream(xmlFile)) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); @@ -278,11 +260,9 @@ validator.setErrorHandler(eh); DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - Document document = docBuilder.parse(new FileInputStream(xmlFile)); + Document document = docBuilder.parse(fis); validator.validate(new DOMSource(document), new DOMResult()); assertFalse(eh.isAnyError()); - } catch (SAXException | ParserConfigurationException | IOException e) { - failUnexpected(e); } } @@ -291,96 +271,88 @@ * Check for the same imported schemas but will use SAXParserFactory and try * parsing using the SAXParser. SCHEMA_SOURCE attribute is using for this * test. + * + * @throws Exception If any errors occur. * @see coins.xsd * @see coinsImportMe.xsd */ - @Test - public void testGetOwnerItemList1() { + @Test(groups = {"readLocalFiles"}) + public void testGetOwnerItemList1() throws Exception { String xsdFile = XML_DIR + "coins.xsd"; String xmlFile = XML_DIR + "coins.xml"; - - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(true); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(true); - SAXParser sp = spf.newSAXParser(); - sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - sp.setProperty(JAXP_SCHEMA_SOURCE, xsdFile); + SAXParser sp = spf.newSAXParser(); + sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + sp.setProperty(JAXP_SCHEMA_SOURCE, xsdFile); - MyErrorHandler eh = new MyErrorHandler(); - sp.parse(new File(xmlFile), eh); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + MyErrorHandler eh = new MyErrorHandler(); + sp.parse(new File(xmlFile), eh); + assertFalse(eh.isAnyError()); } /** * Check usage of javax.xml.datatype.Duration class. + * + * @throws Exception If any errors occur. */ - @Test - public void testGetItemDuration() { + @Test(groups = {"readLocalFiles"}) + public void testGetItemDuration() throws Exception { String xmlFile = XML_DIR + "itemsDuration.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - Document document = dbf.newDocumentBuilder().parse(xmlFile); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + Document document = dbf.newDocumentBuilder().parse(xmlFile); - Element durationElement = (Element) document.getElementsByTagName("sellDuration").item(0); - - NodeList childList = durationElement.getChildNodes(); + Element durationElement = (Element) document.getElementsByTagName("sellDuration").item(0); - for (int i = 0; i < childList.getLength(); i++) { - System.out.println("child " + i + childList.item(i)); - } + NodeList childList = durationElement.getChildNodes(); - Duration duration = DatatypeFactory.newInstance().newDuration("P365D"); - Duration sellDuration = DatatypeFactory.newInstance().newDuration(childList.item(0).getNodeValue()); - assertFalse(sellDuration.isShorterThan(duration)); - assertFalse(sellDuration.isLongerThan(duration)); - assertEquals(sellDuration.getField(DatatypeConstants.DAYS), BigInteger.valueOf(365)); - assertEquals(sellDuration.normalizeWith(new GregorianCalendar(1999, 2, 22)), duration); + for (int i = 0; i < childList.getLength(); i++) { + System.out.println("child " + i + childList.item(i)); + } - Duration myDuration = sellDuration.add(duration); - assertEquals(myDuration.normalizeWith(new GregorianCalendar(2003, 2, 22)), - DatatypeFactory.newInstance().newDuration("P730D")); - } catch (ParserConfigurationException | DatatypeConfigurationException - | SAXException | IOException e) { - failUnexpected(e); - } + Duration duration = DatatypeFactory.newInstance().newDuration("P365D"); + Duration sellDuration = DatatypeFactory.newInstance().newDuration(childList.item(0).getNodeValue()); + assertFalse(sellDuration.isShorterThan(duration)); + assertFalse(sellDuration.isLongerThan(duration)); + assertEquals(sellDuration.getField(DatatypeConstants.DAYS), BigInteger.valueOf(365)); + assertEquals(sellDuration.normalizeWith(new GregorianCalendar(1999, 2, 22)), duration); + + Duration myDuration = sellDuration.add(duration); + assertEquals(myDuration.normalizeWith(new GregorianCalendar(2003, 2, 22)), + DatatypeFactory.newInstance().newDuration("P730D")); } /** * Check usage of TypeInfo interface introduced in DOM L3. + * + * @throws Exception If any errors occur. */ - @Test - public void testGetTypeInfo() { + @Test(groups = {"readLocalFiles"}) + public void testGetTypeInfo() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(new MyErrorHandler()); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(new MyErrorHandler()); - Document document = docBuilder.parse(xmlFile); - Element userId = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "UserID").item(0); - TypeInfo typeInfo = userId.getSchemaTypeInfo(); - assertTrue(typeInfo.getTypeName().equals("nonNegativeInteger")); - assertTrue(typeInfo.getTypeNamespace().equals(W3C_XML_SCHEMA_NS_URI)); + Document document = docBuilder.parse(xmlFile); + Element userId = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "UserID").item(0); + TypeInfo typeInfo = userId.getSchemaTypeInfo(); + assertTrue(typeInfo.getTypeName().equals("nonNegativeInteger")); + assertTrue(typeInfo.getTypeNamespace().equals(W3C_XML_SCHEMA_NS_URI)); - Element role = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Role").item(0); - TypeInfo roletypeInfo = role.getSchemaTypeInfo(); - assertTrue(roletypeInfo.getTypeName().equals("BuyOrSell")); - assertTrue(roletypeInfo.getTypeNamespace().equals(PORTAL_ACCOUNT_NS)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + Element role = (Element)document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Role").item(0); + TypeInfo roletypeInfo = role.getSchemaTypeInfo(); + assertTrue(roletypeInfo.getTypeName().equals("BuyOrSell")); + assertTrue(roletypeInfo.getTypeNamespace().equals(PORTAL_ACCOUNT_NS)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,39 +30,31 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; +import java.io.FilePermission; import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertFalse; - import org.testng.annotations.Test; import org.w3c.dom.Document; -import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; -import static test.auctionportal.HiBidConstants.CLASS_DIR; import static test.auctionportal.HiBidConstants.GOLDEN_DIR; import static test.auctionportal.HiBidConstants.XML_DIR; /** * This is a test class for the Auction portal HiBid.com. */ -public class AuctionItemRepository { +public class AuctionItemRepository extends JAXPFileBaseTest { /** * XML file for parsing. */ @@ -78,94 +70,92 @@ * document that has more than two levels of entity expansion is parsed or * not. Previous system property was changed to jdk.xml.entityExpansionLimit * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + * + * @throws Exception If any errors occur. */ @Test - public void testEntityExpansionSAXPos() { - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - // Secure processing will limit XML processing to conform to - // implementation limits. - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - // Set entityExpansionLimit as 2 should expect fatalError - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); - SAXParser parser = factory.newSAXParser(); + public void testEntityExpansionSAXPos() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect fatalError + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000)); + SAXParser parser = factory.newSAXParser(); - MyErrorHandler fatalHandler = new MyErrorHandler(); - parser.parse(new File(ENTITY_XML), fatalHandler); - assertFalse(fatalHandler.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + MyErrorHandler fatalHandler = new MyErrorHandler(); + setPermissions(new FilePermission(ENTITY_XML, "read")); + parser.parse(new File(ENTITY_XML), fatalHandler); + assertFalse(fatalHandler.isAnyError()); } /** * Setting the EntityExpansion Limit to 2 and checks if the XML * document that has more than two levels of entity expansion is parsed or * not. Previous system property was changed to jdk.xml.entityExpansionLimit * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXParseException.class) - public void testEntityExpansionSAXNeg() throws SAXParseException { - // - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - // Secure processing will limit XML processing to conform to - // implementation limits. - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - // Set entityExpansionLimit as 2 should expect SAXParseException - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - SAXParser parser = factory.newSAXParser(); + public void testEntityExpansionSAXNeg() throws Exception { + SAXParserFactory factory = SAXParserFactory.newInstance(); + // Secure processing will limit XML processing to conform to + // implementation limits. + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + // Set entityExpansionLimit as 2 should expect SAXParseException. + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - MyErrorHandler fatalHandler = new MyErrorHandler(); - parser.parse(new File(ENTITY_XML), fatalHandler); - } catch (SAXParseException e) { - throw e; - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + SAXParser parser = factory.newSAXParser(); + MyErrorHandler fatalHandler = new MyErrorHandler(); + setPermissions(new FilePermission(ENTITY_XML, "read")); + parser.parse(new File(ENTITY_XML), fatalHandler); } /** * Testing set MaxOccursLimit to 10000 in the secure processing enabled for * SAXParserFactory. + * + * @throws Exception If any errors occur. */ @Test - public void testMaxOccurLimitPos() { + public void testMaxOccurLimitPos() throws Exception { String schema_file = XML_DIR + "toys.xsd"; String xml_file = XML_DIR + "toys.xml"; - + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(true); + factory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); + SAXParser parser = factory.newSAXParser(); + parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + setPermissions(new FilePermission(XML_DIR + "-", "read")); + parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); try (InputStream is = new FileInputStream(xml_file)) { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setValidating(true); - factory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000)); - SAXParser parser = factory.newSAXParser(); - parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file)); MyErrorHandler eh = new MyErrorHandler(); parser.parse(is, eh); assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); } } /** * Use a DocumentBuilder to create a DOM object and see if Secure Processing * feature affects the entity expansion. + * + * @throws Exception If any errors occur. */ @Test - public void testEntityExpansionDOMPos() { + public void testEntityExpansionDOMPos() throws Exception { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); try { - DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); - dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000)); - DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - dBuilder.setErrorHandler(eh); + setPermissions(new FilePermission(ENTITY_XML, "read")); dBuilder.parse(ENTITY_XML); assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); + } finally { + setPermissions(); } } @@ -173,310 +163,209 @@ * Use a DocumentBuilder to create a DOM object and see how does the Secure * Processing feature and entityExpansionLimit value affects output. * Negative test that when entityExpansionLimit is too small. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = SAXParseException.class) - public void testEntityExpansionDOMNeg() throws SAXParseException { - try { - DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); - dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); - System.setProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); - DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - dBuilder.setErrorHandler(eh); - dBuilder.parse(ENTITY_XML); - } catch (SAXParseException e) { - throw e; - } catch (ParserConfigurationException | IOException | SAXException e) { - failUnexpected(e); - } + public void testEntityExpansionDOMNeg() throws Exception { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setFeature(FEATURE_SECURE_PROCESSING, true); + setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2)); + DocumentBuilder dBuilder = dfactory.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + dBuilder.setErrorHandler(eh); + setPermissions(new FilePermission(ENTITY_XML, "read")); + dBuilder.parse(ENTITY_XML); } /** * Test xi:include with a SAXParserFactory. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeSAXPos() { - String resultFile = CLASS_DIR + "doc_xinclude.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeSAXPos() throws Exception { + String resultFile = USER_DIR + "doc_xinclude.out"; String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; String xmlFile = XML_DIR + "doc_xinclude.xml"; - try { - try(FileOutputStream fos = new FileOutputStream(resultFile)) { - XInclHandler xh = new XInclHandler(fos, null); - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setXIncludeAware(true); - spf.setFeature(FEATURE_NAME, true); - spf.newSAXParser().parse(new File(xmlFile), xh); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try(FileOutputStream fos = new FileOutputStream(resultFile)) { + XInclHandler xh = new XInclHandler(fos, null); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + spf.newSAXParser().parse(new File(xmlFile), xh); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the simple case of including a document using xi:include using a * DocumentBuilder. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeDOMPos() { - String resultFile = CLASS_DIR + "doc_xincludeDOM.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeDOMPos() throws Exception { + String resultFile = USER_DIR + "doc_xincludeDOM.out"; String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml"; String xmlFile = XML_DIR + "doc_xinclude.xml"; - try { - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - - TransformerFactory.newInstance().newTransformer(). - transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer(). + transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the simple case of including a document using xi:include within a * xi:fallback using a DocumentBuilder. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeFallbackDOMPos() { - String resultFile = CLASS_DIR + "doc_fallbackDOM.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeFallbackDOMPos() throws Exception { + String resultFile = USER_DIR + "doc_fallbackDOM.out"; String goldFile = GOLDEN_DIR + "doc_fallbackGold.xml"; String xmlFile = XML_DIR + "doc_fallback.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test for xi:fallback where the fall back text is parsed as text. This * test uses a nested xi:include for the fallback test. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeFallbackTextPos() { - String resultFile = CLASS_DIR + "doc_fallback_text.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeFallbackTextPos() throws Exception { + String resultFile = USER_DIR + "doc_fallback_text.out"; String goldFile = GOLDEN_DIR + "doc_fallback_textGold.xml"; String xmlFile = XML_DIR + "doc_fallback_text.xml"; - - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the XPointer element() framework with XInclude. + * + * @throws Exception If any errors occur. */ - @Test - public void testXpointerElementPos() { - String resultFile = CLASS_DIR + "doc_xpointer_element.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXpointerElementPos() throws Exception { + String resultFile = USER_DIR + "doc_xpointer_element.out"; String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; String xmlFile = XML_DIR + "doc_xpointer_element.xml"; - - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - - DocumentBuilder db = dbf.newDocumentBuilder(); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(db.parse(new File(xmlFile))), - new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + DocumentBuilder db = dbf.newDocumentBuilder(); + + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(db.parse(new File(xmlFile))), + new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test the XPointer framework with a SAX object. + * + * @throws Exception If any errors occur. */ - @Test - public void testXPointerPos() { - String resultFile = CLASS_DIR + "doc_xpointer.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXPointerPos() throws Exception { + String resultFile = USER_DIR + "doc_xpointer.out"; String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml"; String xmlFile = XML_DIR + "doc_xpointer.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setXIncludeAware(true); - spf.setFeature(FEATURE_NAME, true); - // parse the file - spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setXIncludeAware(true); + spf.setFeature(FEATURE_NAME, true); + // parse the file + spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test if xi:include may reference the doc containing the include if the * parse type is text. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeLoopPos() { - String resultFile = CLASS_DIR + "doc_xinc_loops.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeLoopPos() throws Exception { + String resultFile = USER_DIR + "doc_xinc_loops.out"; String goldFile = GOLDEN_DIR + "doc_xinc_loopGold.xml"; String xmlFile = XML_DIR + "doc_xinc_loops.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document doc = db.parse(new File(xmlFile)); - doc.normalizeDocument(); - doc.setXmlStandalone(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(new File(xmlFile)); + doc.normalizeDocument(); + doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } /** * Test if two non nested xi:include elements can include the same document * with an xi:include statement. + * + * @throws Exception If any errors occur. */ - @Test - public void testXIncludeNestedPos() { - String resultFile = CLASS_DIR + "schedule.out"; + @Test(groups = {"readWriteLocalFiles"}) + public void testXIncludeNestedPos() throws Exception { + String resultFile = USER_DIR + "schedule.out"; String goldFile = GOLDEN_DIR + "scheduleGold.xml"; String xmlFile = XML_DIR + "schedule.xml"; - try{ - try (FileOutputStream fos = new FileOutputStream(resultFile)) { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setXIncludeAware(true); - dbf.setNamespaceAware(true); + try (FileOutputStream fos = new FileOutputStream(resultFile)) { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setXIncludeAware(true); + dbf.setNamespaceAware(true); - Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); - doc.setXmlStandalone(true); - TransformerFactory.newInstance().newTransformer() - .transform(new DOMSource(doc), new StreamResult(fos)); - } - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ParserConfigurationException | SAXException | IOException - | TransformerException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } + Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile)); + doc.setXmlStandalone(true); + TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(doc), new StreamResult(fos)); } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package test.auctionportal; - -import org.w3c.dom.DOMErrorHandler; -import org.w3c.dom.DOMError; - -/** - * Error handler for recording DOM processing error. - */ -public class MyDOMErrorHandler implements DOMErrorHandler { - /** - * flag shows if there is any error. - */ - private volatile boolean errorOccured = false; - - /** - * Set errorOcurred to true when an error occurs. - * @param error The error object that describes the error. This object - * may be reused by the DOM implementation across multiple calls to - * the handleError method. - * @return true that processing may continue depending on. - */ - @Override - public boolean handleError (DOMError error) { - System.err.println( "ERROR" + error.getMessage()); - System.err.println( "ERROR" + error.getRelatedData()); - errorOccured = true; - return true; - } - - /** - * Showing if any error was handled. - * @return true if there is one or more error. - * false no error occurs. - */ - public boolean isError() { - return errorOccured; - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package test.auctionportal; - -import org.w3c.dom.ls.LSOutput; -import java.io.OutputStream; -import java.io.Writer; - -/** - * A Thread-safe LS output destination for DOM processing. LSOutput objects - * belong to the application. The DOM implementation will never modify them - * (though it may make copies and modify the copies, if necessary). - */ -public class MyDOMOutput implements LSOutput { - /** - * An attribute of a language and binding dependent type that represents a - * writable stream of bytes. - */ - private OutputStream bytestream; - - /** - * character encoding to use for the output. - */ - private String encoding; - - /** - * The system identifier. - */ - private String sysId; - - /** - * Writable stream to which 16-bit units can be output. - */ - private Writer writer; - - /** - * An attribute of a language and binding dependent type that represents a - * writable stream of bytes. - * - * @return a writable stream. - */ - @Override - public OutputStream getByteStream() { - return bytestream; - } - - /** - * An attribute of a language and binding dependent type that represents a - * writable stream to which 16-bit units can be output. - * - * @return writable stream instance. - */ - @Override - public Writer getCharacterStream() { - return writer; - } - - /** - * The character encoding to use for the output. - * - * @return the character encoding. - */ - @Override - public String getEncoding() { - return encoding; - } - - /** - * The system identifier for this output destination. - * - * @return system identifier. - */ - @Override - public String getSystemId() { - return sysId; - } - - /** - * Set writable stream of bytes. - * - * @param bs OutputStream instance - */ - @Override - public void setByteStream(OutputStream bs) { - bytestream = bs; - } - - /** - * Set 16 bits unit writable stream. - * - * @param bs a Writer instance - */ - @Override - public void setCharacterStream(Writer cs) { - writer = cs; - } - - /** - * Set character encoding to use for the output. - * - * @param encoding encoding set to the output - */ - @Override - public void setEncoding(String encoding) { - this.encoding = encoding; - } - - /** - * Set the system identifier for the output. - * - * @param sysId system identifier string. - */ - @Override - public void setSystemId(String sysId) { - this.sysId = sysId; - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package test.auctionportal; - -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * ErrorHandler for error handling. Set state if any method in error, warning - * or fatalError was called. - */ -public final class MyErrorHandler extends DefaultHandler { - /** - * Enumeration for ErrorHandler's state. - */ - private enum STATE { ERROR, FATAL, WARNING, NORMAL}; - - /** - * Set state as normal by default. - */ - private volatile STATE state = STATE.NORMAL; - - /** - * Keep exception for further investigation. - */ - private volatile SAXParseException exception; - - /** - * Save exception and set state to ERROR. - * @param e exception wrap error. - */ - @Override - public void error (SAXParseException e) { - state = STATE.ERROR; - exception = e; - } - - /** - * Save exception and set state to FATAL. - * @param e exception wrap error. - */ - @Override - public void fatalError (SAXParseException e) { - state = STATE.FATAL; - exception = e; - } - - /** - * Save exception and set state to WARNING. - * @param e exception wrap error. - */ - @Override - public void warning (SAXParseException e) { - state = STATE.WARNING; - exception = e; - } - - /** - * return ErrorHandle's state . - * @return true No error, fatalError and warning. - * false there is any error, fatalError or warning in processing. - */ - public boolean isAnyError() { - if (state != STATE.NORMAL) - System.out.println(exception); - return state != STATE.NORMAL; - } - - /** - * return whether fatalError is the only error. - * @return true fatalError is the only error. - * false there is no error, or other error besides fatalError. - */ - public boolean isFatalError() { - if (state == STATE.FATAL) - System.out.println(exception); - return state == STATE.FATAL; - } - -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,17 @@ import static com.sun.org.apache.xerces.internal.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; import static org.testng.Assert.assertFalse; import java.io.FileOutputStream; -import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; +import jaxp.library.JAXPFileBaseTest; +import static jaxp.library.JAXPTestUtilities.USER_DIR; import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold; -import static jaxp.library.JAXPTestUtilities.failCleanup; -import static jaxp.library.JAXPTestUtilities.failUnexpected; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; - import org.testng.annotations.Test; import org.w3c.dom.Attr; import org.w3c.dom.Document; @@ -50,8 +46,6 @@ import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSParser; import org.w3c.dom.ls.LSSerializer; -import org.xml.sax.SAXException; -import static test.auctionportal.HiBidConstants.CLASS_DIR; import static test.auctionportal.HiBidConstants.GOLDEN_DIR; import static test.auctionportal.HiBidConstants.PORTAL_ACCOUNT_NS; import static test.auctionportal.HiBidConstants.XML_DIR; @@ -59,141 +53,127 @@ /** * This is the user controller class for the Auction portal HiBid.com. */ -public class UserController { +public class UserController extends JAXPFileBaseTest { /** * Checking when creating an XML document using DOM Level 2 validating * it without having a schema source or a schema location It must throw a * sax parse exception. + * + * @throws Exception If any errors occur. */ @Test - public void testCreateNewUser() { - String resultFile = CLASS_DIR + "accountInfoOut.xml"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + public void testCreateNewUser() throws Exception { + String resultFile = USER_DIR + "accountInfoOut.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - Document document = docBuilder.newDocument(); + Document document = docBuilder.newDocument(); - Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account"); - Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID"); - account.setAttributeNode(accountID); + Element account = document.createElementNS(PORTAL_ACCOUNT_NS, "acc:Account"); + Attr accountID = document.createAttributeNS(PORTAL_ACCOUNT_NS, "acc:accountID"); + account.setAttributeNode(accountID); - account.appendChild(document.createElement("FirstName")); - account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName")); - account.appendChild(document.createElement("UserID")); + account.appendChild(document.createElement("FirstName")); + account.appendChild(document.createElementNS(PORTAL_ACCOUNT_NS, "acc:LastName")); + account.appendChild(document.createElement("UserID")); - DOMImplementationLS impl - = (DOMImplementationLS) DOMImplementationRegistry - .newInstance().getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); - LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); - FileOutputStream output = new FileOutputStream(resultFile); + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); + LSParser builder = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null); + try(FileOutputStream output = new FileOutputStream(resultFile)) { MyDOMOutput domOutput = new MyDOMOutput(); - domOutput.setByteStream(output); writer.write(account, domOutput); docBuilder.parse(resultFile); - - assertTrue(eh.isAnyError()); - } catch (ParserConfigurationException | ClassNotFoundException | - InstantiationException | IllegalAccessException - | ClassCastException | SAXException | IOException e) { - failUnexpected(e); } + assertTrue(eh.isAnyError()); } /** * Checking conflicting namespaces and use renameNode and normalizeDocument. * @see accountInfo.xml + * + * @throws Exception If any errors occur. */ @Test - public void testAddUser() { - String resultFile = CLASS_DIR + "accountRole.out"; + public void testAddUser() throws Exception { + String resultFile = USER_DIR + "accountRole.out"; String xmlFile = XML_DIR + "accountInfo.xml"; - try { - // Copy schema for outputfile - Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), - Paths.get(CLASS_DIR, "accountInfo.xsd"), - StandardCopyOption.REPLACE_EXISTING); - MyErrorHandler eh = new MyErrorHandler(); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + // Copy schema for outputfile + Files.copy(Paths.get(XML_DIR, "accountInfo.xsd"), + Paths.get(USER_DIR, "accountInfo.xsd"), + StandardCopyOption.REPLACE_EXISTING); + MyErrorHandler eh = new MyErrorHandler(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - docBuilder.setErrorHandler(eh); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(xmlFile); - Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0); - Element role = (Element) sell.getParentNode(); + Document document = docBuilder.parse(xmlFile); + Element sell = (Element) document.getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Sell").item(0); + Element role = (Element) sell.getParentNode(); - Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy"); - role.appendChild(buy); + Element buy = (Element) document.renameNode(sell, PORTAL_ACCOUNT_NS, "acc:Buy"); + role.appendChild(buy); - DOMImplementationLS impl - = (DOMImplementationLS) DOMImplementationRegistry - .newInstance().getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); + DOMImplementationLS impl + = (DOMImplementationLS) DOMImplementationRegistry + .newInstance().getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); - try(FileOutputStream output = new FileOutputStream(resultFile)) { - MyDOMOutput mydomoutput = new MyDOMOutput(); - mydomoutput.setByteStream(output); - writer.write(document, mydomoutput); - } + try(FileOutputStream output = new FileOutputStream(resultFile)) { + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(output); + writer.write(document, mydomoutput); + } - docBuilder.parse(resultFile); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + docBuilder.parse(resultFile); + assertFalse(eh.isAnyError()); } /** * Checking Text content in XML file. * @see accountInfo.xml + * + * @throws Exception If any errors occur. */ - @Test - public void testMoreUserInfo() { + @Test(groups = {"readLocalFiles"}) + public void testMoreUserInfo() throws Exception { String xmlFile = XML_DIR + "accountInfo.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - try { - System.out.println("Checking additional user info"); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(xmlFile); - Element account = (Element)document - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); - String textContent = account.getTextContent(); - assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6)); - assertEquals(textContent, "RachelGreen744"); + Document document = docBuilder.parse(xmlFile); + Element account = (Element)document + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "Account").item(0); + String textContent = account.getTextContent(); + assertTrue(textContent.trim().regionMatches(0, "Rachel", 0, 6)); + assertEquals(textContent, "RachelGreen744"); - Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); - assertTrue(accountID.getTextContent().trim().equals("1")); + Attr accountID = account.getAttributeNodeNS(PORTAL_ACCOUNT_NS, "accountID"); + assertTrue(accountID.getTextContent().trim().equals("1")); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + assertFalse(eh.isAnyError()); } /** @@ -204,83 +184,73 @@ * into an XML file which is validated by the schema This covers Row 5 * for the table * http://javaweb.sfbay/~jsuttor/JSR206/jsr-206-html/ch03s05.html. Filed - * bug 4893745 because there was a difference in behavior + * bug 4893745 because there was a difference in behavior. + * + * @throws Exception If any errors occur. */ @Test - public void testCreateUserAccount() { - System.out.println("Creating user account"); + public void testCreateUserAccount() throws Exception { String userXmlFile = XML_DIR + "userInfo.xml"; String accountXmlFile = XML_DIR + "accountInfo.xml"; + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); - - Document document = docBuilder.parse(userXmlFile); - Element user = (Element) document.getElementsByTagName("FirstName").item(0); - // Set schema after parsing userInfo.xml. Otherwise it will conflict - // with DTD validation. - dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); - DocumentBuilder docBuilder1 = dbf.newDocumentBuilder(); - docBuilder1.setErrorHandler(eh); - Document accDocument = docBuilder1.parse(accountXmlFile); + Document document = docBuilder.parse(userXmlFile); + Element user = (Element) document.getElementsByTagName("FirstName").item(0); + // Set schema after parsing userInfo.xml. Otherwise it will conflict + // with DTD validation. + dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI); + DocumentBuilder docBuilder1 = dbf.newDocumentBuilder(); + docBuilder1.setErrorHandler(eh); + Document accDocument = docBuilder1.parse(accountXmlFile); - Element firstName = (Element) accDocument - .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); - Element adoptedAccount = (Element) accDocument.adoptNode(user); + Element firstName = (Element) accDocument + .getElementsByTagNameNS(PORTAL_ACCOUNT_NS, "FirstName").item(0); + Element adoptedAccount = (Element) accDocument.adoptNode(user); - Element parent = (Element) firstName.getParentNode(); - parent.replaceChild(adoptedAccount, firstName); - - DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); - DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); - LSSerializer writer = impl.createLSSerializer(); + Element parent = (Element) firstName.getParentNode(); + parent.replaceChild(adoptedAccount, firstName); - MyDOMOutput mydomoutput = new MyDOMOutput(); - mydomoutput.setByteStream(System.out); - - writer.write(document, mydomoutput); - writer.write(accDocument, mydomoutput); + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS"); + LSSerializer writer = impl.createLSSerializer(); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException - | ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException e) { - failUnexpected(e); - } + MyDOMOutput mydomoutput = new MyDOMOutput(); + mydomoutput.setByteStream(System.out); + + writer.write(document, mydomoutput); + writer.write(accDocument, mydomoutput); + + assertFalse(eh.isAnyError()); } /** * Checking for Row 8 from the schema table when setting the schemaSource * without the schemaLanguage must report an error. + * + * @throws Exception If any errors occur. */ @Test(expectedExceptions = IllegalArgumentException.class) - public void testUserError() throws IllegalArgumentException { - System.out.println("Creating an error in user account"); - + public void testUserError() throws Exception { String xmlFile = XML_DIR + "userInfo.xml"; String schema = "http://java.sun.com/xml/jaxp/properties/schemaSource"; String schemaValue = "http://dummy.com/dummy.xsd"; - try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(true); - dbf.setAttribute(schema, schemaValue); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + dbf.setValidating(true); + dbf.setAttribute(schema, schemaValue); - DocumentBuilder docBuilder = dbf.newDocumentBuilder(); - MyErrorHandler eh = new MyErrorHandler(); - docBuilder.setErrorHandler(eh); - Document document = docBuilder.parse(xmlFile); - assertFalse(eh.isAnyError()); - } catch (ParserConfigurationException | SAXException | IOException e) { - failUnexpected(e); - } + DocumentBuilder docBuilder = dbf.newDocumentBuilder(); + MyErrorHandler eh = new MyErrorHandler(); + docBuilder.setErrorHandler(eh); + docBuilder.parse(xmlFile); + assertFalse(eh.isAnyError()); } /** @@ -288,10 +258,12 @@ * @see screenName.xml has prefix of * userName is bound to "http://hibid.com/user" namespace normalization * will create a namespace of prefix us and attach userEmail. + * + * @throws Exception If any errors occur. */ @Test - public void testCheckScreenNameExists() { - String resultFile = CLASS_DIR + "screenName.out"; + public void testCheckScreenNameExists() throws Exception { + String resultFile = USER_DIR + "screenName.out"; String xmlFile = XML_DIR + "screenName.xml"; String goldFile = GOLDEN_DIR + "screenNameGold.xml"; @@ -318,21 +290,7 @@ MyDOMOutput domoutput = new MyDOMOutput(); domoutput.setByteStream(output); writer.write(document, domoutput); - - assertTrue(compareDocumentWithGold(goldFile, resultFile)); - } catch (ClassNotFoundException | InstantiationException - | IllegalAccessException | ClassCastException | IOException - | ParserConfigurationException | SAXException e) { - failUnexpected(e); - } finally { - try { - Path resultPath = Paths.get(resultFile); - if (Files.exists(resultPath)) { - Files.delete(resultPath); - } - } catch (IOException ex) { - failCleanup(ex, resultFile); - } } + assertTrue(compareDocumentWithGold(goldFile, resultFile)); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package test.auctionportal; - -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.util.stream.Collectors; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.ext.LexicalHandler; -import org.xml.sax.helpers.DefaultHandler; - -/** - * A SAX2 event handlers. - * This SAX2 ContentHandler receives callback event then print whole document - * that is parsed. - */ -public class XInclHandler extends DefaultHandler implements LexicalHandler { - /** - * Print writer. - */ - private final PrintWriter fOut; - - /** - * Canonical output. - */ - private volatile boolean fCanonical; - - /** - * Element depth. - */ - private volatile int fElementDepth; - - /** - * Sets whether output is canonical. - */ - public void setCanonical(boolean canonical) { - fCanonical = canonical; - } - - /** - * Sets the output stream for printing. - * @param stream OutputStream for message output. - * @param encoding File encoding for message output. - */ - public XInclHandler(OutputStream stream, String encoding) - throws UnsupportedEncodingException { - // At least set one encoding. - if (encoding == null) { - encoding = "UTF8"; - } - - fOut = new PrintWriter(new OutputStreamWriter(stream, encoding), false); - } - - /** - * Receive notification of the beginning of the document. Write the start - * document tag if it's not canonical mode. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - */ - @Override - public void startDocument() throws SAXException { - fElementDepth = 0; - - if (!fCanonical) { - writeFlush(""); - } - } - - /** - * Receive notification of a processing instruction. - * @param target The processing instruction target. - * @param data The processing instruction data, or null if - * none is supplied. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - */ - @Override - public void processingInstruction (String target, String data) - throws SAXException { - if (fElementDepth > 0) { - StringBuilder instruction = new StringBuilder(" 0) { - instruction.append(' ').append(data); - } - instruction.append("?>"); - writeFlush(instruction.toString()); - } - } - - /** - * Receive notification of the start of an element then write the normalized - * output to the file. - * @param uri The Namespace URI, or the empty string if the - * element has no Namespace URI or if Namespace - * processing is not being performed. - * @param localName The local name (without prefix), or the - * empty string if Namespace processing is not being - * performed. - * @param qName The qualified name (with prefix), or the - * empty string if qualified names are not available. - * @param attributes The attributes attached to the element. If - * there are no attributes, it shall be an empty - * Attributes object. - */ - @Override - public void startElement(String uri, String local, String raw, - Attributes attrs) throws SAXException { - fElementDepth++; - StringBuilder start = new StringBuilder().append('<').append(raw); - if (attrs != null) { - for (int i = 0; i < attrs.getLength(); i++) { - start.append(' ').append(attrs.getQName(i)).append("=\""). - append(normalizeAndPrint(attrs.getValue(i))).append('"'); - } - } - start.append('>'); - writeFlush(start.toString()); - } - - /** - * Receive notification of character data inside an element and write - * normalized characters to file. - * @param ch The characters. - * @param start The start position in the character array. - * @param length The number of characters to use from the - * character array. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - */ - @Override - public void characters(char ch[], int start, int length) - throws SAXException { - writeFlush(normalizeAndPrint(ch, start, length)); - } - - /** - * Receiving notification of ignorable whitespace in element content and - * writing normalized ignorable characters to file. - * @param ch The characters. - * @param start The start position in the character array. - * @param length The number of characters to use from the - * character array. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - */ - @Override - public void ignorableWhitespace(char ch[], int start, int length) - throws SAXException { - characters(ch, start, length); - } - - /** - * Receive notification of the end of an element and print end element. - * - * @param uri The Namespace URI, or the empty string if the - * element has no Namespace URI or if Namespace - * processing is not being performed. - * @param localName The local name (without prefix), or the - * empty string if Namespace processing is not being - * performed. - * @param qName The qualified name (with prefix), or the - * empty string if qualified names are not available. - */ - @Override - public void endElement(String uri, String local, String raw) - throws SAXException { - fElementDepth--; - writeFlush(""); - } - - /** - * Receive notification of a parser warning and print it out. - * @param e The warning information encoded as an exception. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - */ - @Override - public void warning(SAXParseException ex) throws SAXException { - printError("Warning", ex); - } - - /** - * Receive notification of a parser error and print it out. - * @param e The error information encoded as an exception. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - - */ - @Override - public void error(SAXParseException ex) throws SAXException { - printError("Error", ex); - } - - /** - * Receive notification of a parser fatal error. Throw out fatal error - * following print fatal error message. - * @param e The fatal error information encoded as an exception. - * @exception org.xml.sax.SAXException Any SAX exception, possibly - * wrapping another exception. - - */ - @Override - public void fatalError(SAXParseException ex) throws SAXException { - printError("Fatal Error", ex); - throw ex; - } - - /** - * Do nothing on start DTD. - * @param name The document type name. - * @param publicId The declared public identifier for the - * external DTD subset, or null if none was declared. - * @param systemId The declared system identifier for the - * external DTD subset, or null if none was declared. - * (Note that this is not resolved against the document - * base URI.) - * @exception SAXException The application may raise an - * exception. - */ - @Override - public void startDTD(String name, String publicId, String systemId) - throws SAXException { - } - - /** - * Do nothing on end DTD. - * @exception SAXException The application may raise an exception. - */ - @Override - public void endDTD() throws SAXException { - } - - /** - * Do nothing on start entity. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%', and if it is the - * external DTD subset, it will be "[dtd]". - * @exception SAXException The application may raise an exception. - */ - @Override - public void startEntity(String name) throws SAXException { - } - - /** - * Do nothing on end entity. - * @param name The name of the entity. If it is a parameter - * entity, the name will begin with '%', and if it is the - * external DTD subset, it will be "[dtd]". - * @exception SAXException The application may raise an exception. - */ - @Override - public void endEntity(String name) throws SAXException { - } - - /** - * Do nothing on start CDATA section. - * @exception SAXException The application may raise an exception. - */ - @Override - public void startCDATA() throws SAXException { - } - - /** - * Do nothing on end CDATA section. - * @exception SAXException The application may raise an exception. - */ - @Override - public void endCDATA() throws SAXException { - } - - /** - * Report an normalized XML comment when receive a comment in the document. - * - * @param ch An array holding the characters in the comment. - * @param start The starting position in the array. - * @param length The number of characters to use from the array. - * @exception SAXException The application may raise an exception. - */ - @Override - public void comment(char ch[], int start, int length) throws SAXException { - if (!fCanonical && fElementDepth > 0) { - writeFlush(""); - } - } - - /** - * Normalizes and prints the given string. - * @param s String to be normalized - */ - private String normalizeAndPrint(String s) { - return s.chars().mapToObj(c -> normalizeAndPrint((char)c)). - collect(Collectors.joining()); - } - - /** - * Normalizes and prints the given array of characters. - * @param ch The characters to be normalized. - * @param start The start position in the character array. - * @param length The number of characters to use from the - * character array. - */ - private String normalizeAndPrint(char[] ch, int offset, int length) { - return normalizeAndPrint(new String(ch, offset, length)); - } - - /** - * Normalizes given character. - * @param c char to be normalized. - */ - private String normalizeAndPrint(char c) { - switch (c) { - case '<': - return "<"; - case '>': - return ">"; - case '&': - return "&"; - case '"': - return """; - case '\r': - case '\n': - return fCanonical ? "&#" + Integer.toString(c) + ";" : String.valueOf(c); - default: - return String.valueOf(c); - } - } - - /** - * Prints the error message. - * @param type error type - * @param ex exception that need to be printed - */ - private void printError(String type, SAXParseException ex) { - System.err.print("[" + type + "] "); - String systemId = ex.getSystemId(); - if (systemId != null) { - int index = systemId.lastIndexOf('/'); - if (index != -1) - systemId = systemId.substring(index + 1); - System.err.print(systemId); - } - System.err.print(':' + ex.getLineNumber()); - System.err.print(':' + ex.getColumnNumber()); - System.err.println(": " + ex.getMessage()); - System.err.flush(); - } - - /** - * Write out and flush. - * @param out string to be written. - */ - private void writeFlush(String out) { - fOut.print(out); - fOut.flush(); - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.xml.parsers.ptests; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import static jaxp.library.JAXPTestUtilities.ERROR_MSG_HEADER; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.LocatorImpl; + +/** + * Customized DefaultHandler which writes output document when methods are + * called by Transformer. Test may use output document to compare with golden + * file for verification. + */ +class MyCHandler extends DefaultHandler implements AutoCloseable { + + private final BufferedWriter bWriter; + private final Locator locator = new LocatorImpl(); + + private MyCHandler(File file) throws IOException { + bWriter = new BufferedWriter(new FileWriter(file)); + } + + public static MyCHandler newInstance(File file) throws IOException { + MyCHandler handler = new MyCHandler(file); + return handler; + } + + @Override + public void characters(char[] ch, int start, int length) { + String s = new String(ch, start, length); + String str = String.format("characters...length is:%d\n<%s>", s.length(), s); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void endDocument() { + String str = "endDocument..."; + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + bWriter.flush(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void endElement(String namespaceURI, String localName, String qName) { + String str = String.format("endElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s>", namespaceURI, localName, qName); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void endPrefixMapping(String prefix) { + String str = String.format("endPrefixMapping...\nprefix: <%s>", prefix); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void ignorableWhitespace(char[] ch, int start, int length) { + String s = new String(ch, start, length); + String str = String.format("ignorableWhitespace...\n%s ignorable white space string length: %d", s, s.length()); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void processingInstruction(String target, String data) { + String str = String.format("processingInstruction...target:<%s> data: <%s>", target, data); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void skippedEntity(String name) { + String str = String.format("skippedEntity...\nname: <%s>", name); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void startDocument() { + String str = "startDocument..."; + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { + String str = String.format("startElement...\nnamespaceURI: <%s> localName: <%s> qName: <%s> Number of Attributes: <%d> Line# <%d>", namespaceURI, + localName, qName, atts.getLength(), locator.getLineNumber()); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void startPrefixMapping(String prefix, String uri) { + String str = String.format("startPrefixMapping...\nprefix: <%s> uri: <%s>", prefix, uri); + try { + bWriter.write(str, 0, str.length()); + bWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException(ERROR_MSG_HEADER, e); + } + } + + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.xml.parsers.ptests; + +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Customized DefaultHandler used for SAXParseException testing. + */ +class MyErrorHandler extends DefaultHandler { + /** + * Flag whether any event was received. + */ + private volatile boolean errorOccured; + + /** + * Set no event received on constructor. + */ + private MyErrorHandler() { + errorOccured = false; + } + + /** + * Factory method to create a MyErrorHandler instance. + * @return a MyErrorHandler instance. + */ + public static MyErrorHandler newInstance() { + return new MyErrorHandler(); + } + + /** + * Receive notification of a recoverable error. + * @param e a recoverable parser exception error. + */ + @Override + public void error(SAXParseException e) { + errorOccured = true; + } + + /** + * Receive notification of a parser warning. + * @param e a parser warning event. + */ + @Override + public void warning(SAXParseException e) { + errorOccured = true; + } + + /** + * Report a fatal XML parsing error. + * @param e The error information encoded as an exception. + */ + @Override + public void fatalError(SAXParseException e) { + errorOccured = true; + } + + /** + * Has any event been received. + * + * @return true if any event has been received. + * false if no event has been received. + */ + public boolean isErrorOccured() { + return errorOccured; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package javax.xml.parsers.ptests; + +import static jaxp.library.JAXPTestUtilities.FILE_SEP; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; + + +/** + * Utility interface which includes final variables of XML, golden file + * directories. + */ +public class ParserTestConst { + /** + * XML source file directory. + */ + public static final String XML_DIR = getPathByClassName(ParserTestConst.class, + ".." + FILE_SEP + "xmlfiles"); + + + /** + * Golden validation files directory. + */ + public static final String GOLDEN_DIR = getPathByClassName(ParserTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,40 +23,22 @@ package javax.xml.transform.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for JAXP functional test */ public class TransformerTestConst { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; + public static final String XML_DIR = getPathByClassName(TransformerTestConst.class, + ".." + FILE_SEP + "xmlfiles"); - /** - * Package name that separates by slash. - */ - public static final String PACKAGE_NAME = FILE_SEP + - TransformerTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); /** - * Test base directory. Every package has its own test package directory. - */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. + * Golden validation files directory. */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; - - /** - * Golden output file directory. We pre-define all expected output in golden - * output file. Test verifies whether the standard output is same as content - * of golden file. - */ - public static final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(TransformerTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java --- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,27 +23,15 @@ package javax.xml.xpath.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for XPath functional test */ public class XPathTestConst { /** - * Package name that separates by slash. - */ - public static final String PACKAGE_NAME = FILE_SEP + - XPathTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - - /** - * Test base directory. Every package has its own test package directory. + * XML source file directory. */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. - */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; + public static final String XML_DIR = getPathByClassName(XPathTestConst.class, + ".." + FILE_SEP + "xmlfiles"); } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.security.Permission; +import java.security.Permissions; +import java.security.Policy; +import java.util.PropertyPermission; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +/** + * This is a base class that every test class must extend if it needs to be run + * with security mode. + */ +public class JAXPBaseTest { + /** + * Backing up policy. + */ + protected static Policy policy; + + /** + * Backing up security manager. + */ + private static SecurityManager sm; + + /* + * Install a SecurityManager along with a base Policy to allow testNG to + * run when there is a security manager. + */ + @BeforeClass + public void setUpClass() throws Exception { + setPolicy(new TestPolicy()); + System.setSecurityManager(new SecurityManager()); + } + + /* + * Install the original Policy and SecurityManager when there is a security + * manager. + */ + @AfterClass + public void tearDownClass() throws Exception { + System.setSecurityManager(sm); + setPolicy(policy); + } + + /* + * Utility Method used to set the current Policy. + */ + protected static void setPolicy(Policy p) { + Policy.setPolicy(p); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permission... ps) { + Policy.setPolicy(new TestPolicy(ps)); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permissions ps) { + Policy.setPolicy(new TestPolicy(ps)); + } + + /** + * Backing up policy and security manager for restore when there is a + * security manager. + */ + public JAXPBaseTest() { + policy = Policy.getPolicy(); + sm = System.getSecurityManager(); + } + + /** + * Safety acquire a system property. + * Note invocation of this method will restore permission to limited + * minimal permission of tests. If there is additional permission set + * already, you need restore permission by yourself. + * @param propName System property name to be acquired. + * @return property value + */ + protected String getSystemProperty(final String propName) { + setPermissions(new PropertyPermission(propName, "read")); + try { + return System.getProperty(propName); + } finally { + setPermissions(); + } + } + + /** + * Safety set a system property by given system value. + * + * @param propName System property name to be set. + * @param propValue System property value to be set. + */ + protected void setSystemProperty(final String propName, final String propValue) { + setPermissions(new PropertyPermission(propName, "write")); + try { + if (propValue == null) { + System.clearProperty(propName); + } else { + System.setProperty(propName, propValue); + } + } finally { + setPermissions(); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.io.FilePermission; +import java.security.Permission; +import java.security.Permissions; +import java.security.Policy; +import static jaxp.library.JAXPBaseTest.setPolicy; +import org.testng.annotations.BeforeClass; + +/** + * This is a base class that every test class that need to access local XML + * files must extend if it needs to be run with security mode. + */ +public class JAXPFileBaseTest extends JAXPBaseTest { + /* + * Install a SecurityManager along with a base Policy to allow testNG to + * run when there is a security manager. + */ + @BeforeClass + @Override + public void setUpClass() throws Exception { + setPolicy(new FileTestPolicy()); + System.setSecurityManager(new SecurityManager()); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permission... ps) { + Policy.setPolicy(new FileTestPolicy(ps)); + } + + /* + * Add the specified permission(s) to the test policy. + * Note there is no way to add permissions to current permissions. Reset + * test policy by setting minimal permmisons in addition to specified + * permissions when calling this method. + */ + protected static void setPermissions(Permissions ps) { + Policy.setPolicy(new FileTestPolicy(ps)); + } +} + +/** + * This policy is only given to tests that need access local files. Additional + * permissions for accessing local files have been granted by default. + * @author HaiboYan + */ +class FileTestPolicy extends TestPolicy { + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + * @param ps permissions to be added. + */ + public FileTestPolicy(Permissions ps) { + super(ps); + } + + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + * @param ps permission array to be added. + */ + public FileTestPolicy(Permission... ps) { + super(ps); + } + + /** + * Defines the minimal permissions required by testNG when running these + * tests + */ + @Override + protected void setMinimalPermissions() { + super.setMinimalPermissions(); + permissions.add(new FilePermission(System.getProperty("user.dir") + "/-", + "read, write")); + permissions.add(new FilePermission(System.getProperty("test.src") + "/-", + "read")); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.io.FilePermission; +import static jaxp.library.JAXPBaseTest.setPermissions; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; + +/** + * This is a base class that every test class that need to reading local XML + * files must extend if it needs to be run with security mode. + */ +public class JAXPFileReadOnlyBaseTest extends JAXPBaseTest { + /** + * Source files/XML files directory. + */ + private final String SRC_DIR = getSystemProperty("test.src"); + + /** + * Allowing access local file system for this group. + */ + @BeforeGroups (groups = {"readLocalFiles"}) + public void setFilePermissions() { + setPermissions(new FilePermission(SRC_DIR + "/-", "read")); + } + + /** + * Restore the system property. + */ + @AfterGroups (groups = {"readLocalFiles"}) + public void restoreFilePermissions() { + setPermissions(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java --- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,21 +23,34 @@ package jaxp.library; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import static org.testng.Assert.fail; import org.w3c.dom.Document; +import org.w3c.dom.Node; import org.xml.sax.SAXException; /** @@ -61,14 +74,17 @@ public static final String FILE_SEP = "/"; /** - * User home. + * Current test directory. */ - public static final String USER_DIR = System.getProperty("user.dir", "."); + public static final String USER_DIR = + System.getProperty("user.dir", ".") + FILE_SEP;; /** - * TEMP file directory. + * A map storing every test's current test file pointer. File number should + * be incremental and it's a thread-safe reading on this file number. */ - public static final String TEMP_DIR = System.getProperty("java.io.tmpdir", "."); + private static final ConcurrentHashMap currentFileNumber + = new ConcurrentHashMap<>(); /** * BOM table for storing BOM header. @@ -94,12 +110,60 @@ * @return true if two files are identical. * false if two files are not identical. * @throws IOException if an I/O error occurs reading from the file or a - * malformed or unmappable byte sequence is read + * malformed or unmappable byte sequence is read. */ public static boolean compareWithGold(String goldfile, String outputfile) throws IOException { + return compareWithGold(goldfile, outputfile, StandardCharsets.UTF_8); + } + + /** + * Compare contents of golden file with test output file line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param outputfile Test output file name. + * @param cs the charset to use for decoding. + * @return true if two files are identical. + * false if two files are not identical. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read. + */ + public static boolean compareWithGold(String goldfile, String outputfile, + Charset cs) throws IOException { return Files.readAllLines(Paths.get(goldfile)). - equals(Files.readAllLines(Paths.get(outputfile))); + equals(Files.readAllLines(Paths.get(outputfile), cs)); + } + + /** + * Compare contents of golden file with test output list line by line. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param lines test output list. + * @return true if file's content is identical to given list. + * false if file's content is not identical to given list. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareLinesWithGold(String goldfile, List lines) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).equals(lines); + } + + /** + * Compare contents of golden file with a test output string. + * return true if they're identical. + * @param goldfile Golden output file name. + * @param string test string. + * @return true if file's content is identical to given string. + * false if file's content is not identical to given string. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read + */ + public static boolean compareStringWithGold(String goldfile, String string) + throws IOException { + return Files.readAllLines(Paths.get(goldfile)).stream().collect( + Collectors.joining(System.getProperty("line.separator"))) + .equals(string); } /** @@ -132,6 +196,35 @@ resultD.normalizeDocument(); return goldD.isEqualNode(resultD); } + + /** + * Compare contents of golden file with the serialization represent by given + * DOM node. + * Here we ignore the white space and comments. return true if they're + * lexical identical. + * @param goldfile Golden output file name. + * @param node A DOM node instance. + * @return true if file's content is identical to given node's serialization + * represent. + * false if file's content is not identical to given node's + * serialization represent. + * @throws TransformerException If an unrecoverable error occurs during the + * course of the transformation.. + * @throws IOException if an I/O error occurs reading from the file or a + * malformed or unmappable byte sequence is read . + */ + public static boolean compareSerializeDOMWithGold(String goldfile, Node node) + throws TransformerException, IOException { + TransformerFactory factory = TransformerFactory.newInstance(); + // Use identity transformer to serialize + Transformer identityTransformer = factory.newTransformer(); + StringWriter sw = new StringWriter(); + StreamResult streamResult = new StreamResult(sw); + DOMSource nodeSource = new DOMSource(node); + identityTransformer.transform(nodeSource, streamResult); + return compareStringWithGold(goldfile, sw.toString()); + } + /** * Convert stream to ByteArrayInputStream by given character set. * @param charset target character set. @@ -159,6 +252,36 @@ return new ByteArrayInputStream(bb.array()); } + /** + * Worker method to detect common absolute URLs. + * + * @param s String path\filename or URL (or any, really) + * @return true if s starts with a common URI scheme (namely + * the ones found in the examples of RFC2396); false otherwise + */ + protected static boolean isCommonURL(String s) { + if (null == s) + return false; + return Pattern.compile("^(file:|http:|ftp:|gopher:|mailto:|news:|telnet:)") + .matcher(s).matches(); + } + + /** + * Utility method to translate a String filename to URL. + * + * If the name starts with a common URI scheme (namely the ones + * found in the examples of RFC2396), then simply return the + * name as-is (the assumption is that it's already a URL). + * Otherwise we attempt (cheaply) to convert to a file:/ URL. + * + * @param filename local path/filename of a file. + * @return a file:/ URL if filename represent a file, the same string if + * it appears to already be a URL. + */ + public static String filenameToURL(String filename) { + return Paths.get(filename).toUri().toASCIIString(); + } + /** * Prints error message if an exception is thrown * @param ex The exception is thrown by test. @@ -175,4 +298,38 @@ public static void failCleanup(IOException ex, String name) { fail(String.format(ERROR_MSG_CLEANUP, name), ex); } + + /** + * Retrieve next test output file name. This method is a thread-safe method. + * @param clazz test class. + * @return next test output file name. + */ + public static String getNextFile(Class clazz) { + int nextNumber = currentFileNumber.contains(clazz) + ? currentFileNumber.get(clazz) + 1 : 1; + Integer i = currentFileNumber.putIfAbsent(clazz, nextNumber); + if (i != null && i != nextNumber) { + do { + nextNumber = currentFileNumber.get(clazz) + 1; + } while (currentFileNumber.replace(clazz, nextNumber -1, nextNumber)); + } + return USER_DIR + clazz.getName() + nextNumber + ".out"; + } + + /** + * Acquire a full path string by given class name and relative path string. + * @param clazz Class name for the test. + * @param relativeDir relative path between java source file and expected + * path. + * @return a string represents the full path of accessing path. + */ + public static String getPathByClassName(Class clazz, String relativeDir) { + String packageName = FILE_SEP + + clazz.getPackage().getName().replaceAll("[.]", FILE_SEP); + String javaSourcePath = System.getProperty("test.src").replaceAll("\\" + File.separator, FILE_SEP) + + packageName + FILE_SEP; + String normalizedPath = Paths.get(javaSourcePath, relativeDir).normalize(). + toAbsolutePath().toString(); + return normalizedPath.replace("\\", FILE_SEP) + FILE_SEP; + } } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jaxp.library; + +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.security.SecurityPermission; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.PropertyPermission; +import java.util.StringJoiner; + +/* + * Simple Policy class that supports the required Permissions to validate the + * JAXP concrete classes. + * Note: permission can only be added. You may want to create a new TestPolicy + * instance if you need remove permissions. + */ +public class TestPolicy extends Policy { + protected final PermissionCollection permissions = new Permissions(); + + /** + * Constructor which sets the minimum permissions by default allowing testNG + * to work with a SecurityManager. + */ + public TestPolicy() { + setMinimalPermissions(); + } + + /** + * Construct an instance with the minimal permissions required by the test + * environment and additional permission(s) as specified. + * @param ps permissions to be added. + */ + public TestPolicy(Permissions ps) { + setMinimalPermissions(); + TestPolicy.this.addPermissions(ps); + } + + /** + * Construct an instance with the minimal permissions required by the test + * environment and additional permission(s) as specified. + * @param ps permission array to be added. + */ + public TestPolicy(Permission... ps) { + setMinimalPermissions(); + addPermissions(ps); + } + + /** + * Defines the minimal permissions required by testNG when running these + * tests + */ + protected void setMinimalPermissions() { + permissions.add(new SecurityPermission("getPolicy")); + permissions.add(new SecurityPermission("setPolicy")); + permissions.add(new RuntimePermission("getClassLoader")); + permissions.add(new RuntimePermission("setSecurityManager")); + permissions.add(new RuntimePermission("createSecurityManager")); + permissions.add(new PropertyPermission("testng.show.stack.frames", + "read")); + permissions.add(new PropertyPermission("user.dir", "read")); + permissions.add(new PropertyPermission("test.src", "read")); + permissions.add(new PropertyPermission("file.separator", "read")); + permissions.add(new PropertyPermission("line.separator", "read")); + permissions.add(new PropertyPermission("fileStringBuffer", "read")); + permissions.add(new PropertyPermission("dataproviderthreadcount", "read")); + } + + /* + * Add permissions for your tests. + * @param permissions to be added. + */ + private void addPermissions(Permissions ps) { + Collections.list(ps.elements()).forEach(p -> permissions.add(p)); + } + + + /* + * Add permissions for your tests. + * @param permissions to be added. + */ + private void addPermissions(Permission[] ps) { + Arrays.stream(ps).forEach(p -> permissions.add(p)); + } + + /** + * Set all permissions. Caution: this should not called carefully unless + * it's really needed. + */ + private void setAllPermissions() { + permissions.add(new AllPermission()); + } + + /* + * Overloaded methods from the Policy class. + */ + @Override + public String toString() { + StringJoiner sj = new StringJoiner("\n", "policy: ", ""); + Enumeration perms = permissions.elements(); + while (perms.hasMoreElements()) { + sj.add(perms.nextElement().toString()); + } + return sj.toString(); + + } + + @Override + public PermissionCollection getPermissions(ProtectionDomain domain) { + return permissions; + } + + @Override + public PermissionCollection getPermissions(CodeSource codesource) { + return permissions; + } + + @Override + public boolean implies(ProtectionDomain domain, Permission perm) { + return permissions.implies(perm); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.xml.sax.ptests; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Simple attributes handler. + */ +public class MyAttrCHandler extends DefaultHandler { + /** + * FileWriter to write string to output file. + */ + private final BufferedWriter bWriter; + + /** + * Initiate FileWriter + * @param fileName output file name. + * @throws IOException + */ + public MyAttrCHandler(String fileName) throws IOException { + bWriter = new BufferedWriter(new FileWriter(fileName)); + } + + /** + * Write element content before start access every element. + * @throws org.xml.sax.SAXException + */ + @Override + public void startElement(String uri, String localName, + String qName, Attributes attributes) throws SAXException { + try { + String string = "uri <" + uri + "> localName <" + localName + + "> qName <" + qName + ">"; + + bWriter.write( string, 0, string.length()); + bWriter.newLine(); + + int length = attributes.getLength(); + string = "length: " + length; + + bWriter.write( string, 0, string.length()); + bWriter.newLine(); + + for (int ind=0; ind < length ; ind++) { + string = "For index = " + ind + "\n"; + string += "getLocalName <" + attributes.getLocalName(ind) + +">" + "\n"; + string += "getQName <" + attributes.getQName(ind) +">" + "\n"; + string += "getType <" + attributes.getType(ind) +">" + "\n"; + string += "getURI <" + attributes.getURI(ind) +">" + "\n"; + string += "getValue <" + attributes.getValue(ind) +">" + "\n"; + + bWriter.write( string, 0, string.length()); + bWriter.newLine(); + + String gotLocalName = attributes.getLocalName(ind); + String gotQName = attributes.getQName(ind); + String gotURI = attributes.getURI(ind); + + string ="Using localName, qname and uri pertaining to index = " + + ind; + bWriter.write( string, 0, string.length()); + bWriter.newLine(); + + string = "getIndex(qName) <" + attributes.getIndex(gotQName) + +">" + "\n"; + string += "getIndex(uri, localName) <" + + attributes.getIndex(gotURI, gotLocalName) +">" + "\n"; + + string += "getType(qName) <" + + attributes.getType(gotQName) +">" + "\n"; + string += "getType(uri, localName) <" + + attributes.getType(gotURI, gotLocalName) +">" + "\n"; + + string += "getValue(qName) <" + + attributes.getValue(gotQName) +">" + "\n"; + string += "getValue(uri, localName) <" + + attributes.getValue(gotURI, gotLocalName) +">" + "\n"; + + bWriter.write( string, 0, string.length()); + bWriter.newLine(); + } + bWriter.newLine(); + } catch(IOException ex){ + throw new SAXException(ex); + } + } + + /** + * Flush the stream and close the file. + * @throws IOException when writing or closing file failed. + */ + public void flushAndClose() throws IOException { + bWriter.flush(); + bWriter.close(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.xml.sax.ptests; + +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.LocatorImpl; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.FileWriter; +import org.xml.sax.SAXException; + +class MyNSContentHandler extends DefaultHandler implements AutoCloseable{ + /** + * Prefix for written string. + */ + private final static String WRITE_ERROR = "bWrite error"; + + /** + * FileWriter to write output file. + */ + private final BufferedWriter bWriter; + + /** + * Default locator. + */ + Locator locator = new LocatorImpl(); + + /** + * Initiate FileWrite. + * @param outputFileName file name of output file. + * @throws SAXException when open output file failed. + */ + public MyNSContentHandler(String outputFileName) throws SAXException { + try { + bWriter = new BufferedWriter(new FileWriter(outputFileName)); + } catch (IOException ex) { + throw new SAXException(ex); + } + } + + /** + * Write characters tag along with content of characters when meet + * characters event. + * @throws IOException error happen when writing file. + */ + @Override + public void characters(char[] ch, int start, int length) + throws SAXException { + String s = new String(ch, start, length); + println("characters...length is:" + s.length() + "\n" + + "<" + s + ">"); + } + + /** + * Write endDocument tag then flush the content and close the file when meet + * endDocument event. + * @throws IOException error happen when writing file or closing file. + */ + @Override + public void endDocument() throws SAXException { + try { + println("endDocument..."); + bWriter.flush(); + bWriter.close(); + } catch (IOException ex) { + throw new SAXException(WRITE_ERROR, ex); + } + } + + /** + * Write endElement tag with namespaceURI, localName, qName to the file when + * meet endElement event. + * @throws IOException error happen when writing file. + */ + @Override + public void endElement(String namespaceURI, String localName, String qName) + throws SAXException { + println("endElement...\n" + "namespaceURI: <" + namespaceURI + + "> localName: <" + localName + "> qName: <" + qName + ">"); + } + + /** + * Write endPrefixMapping tag along with prefix to the file when meet + * endPrefixMapping event. + * @throws IOException error happen when writing file. + */ + @Override + public void endPrefixMapping(String prefix) throws SAXException { + println("endPrefixMapping...\n" + "prefix: <" + prefix + ">"); + } + + /** + * Write ignorableWhitespace tag along with white spaces when meet + * ignorableWhitespace event. + * @throws IOException error happen when writing file. + */ + @Override + public void ignorableWhitespace(char[] ch, int start, int length) + throws SAXException { + String s = new String(ch, start, length); + println("ignorableWhitespace...\n" + s + + " ignorable white space string length: " + s.length()); + } + + /** + * Write processingInstruction tag along with target name and target data + * when meet processingInstruction event. + * @throws IOException error happen when writing file. + */ + @Override + public void processingInstruction(String target, String data) + throws SAXException { + println("processingInstruction...target:<" + target + + "> data: <" + data + ">"); + } + + /** + * Write setDocumentLocator tag when meet setDocumentLocator event. + */ + @Override + public void setDocumentLocator(Locator locator) { + try { + this.locator = locator; + println("setDocumentLocator..."); + } catch (SAXException ex) { + System.err.println(WRITE_ERROR + ex); + } + } + + /** + * Write skippedEntity tag along with entity name when meet skippedEntity + * event. + * @throws IOException error happen when writing file. + */ + @Override + public void skippedEntity(String name) throws SAXException { + println("skippedEntity...\n" + "name: <" + name + ">"); + } + + /** + * Write startDocument tag when meet startDocument event. + * @throws IOException error happen when writing file. + */ + @Override + public void startDocument() throws SAXException { + println("startDocument..."); + } + + /** + * Write startElement tag along with namespaceURI, localName, qName, number + * of attributes and line number when meet startElement event. + * @throws IOException error happen when writing file. + */ + @Override + public void startElement(String namespaceURI, String localName, + String qName, Attributes atts) throws SAXException { + println("startElement...\n" + "namespaceURI: <" + namespaceURI + + "> localName: <" + localName + "> qName: <" + qName + + "> Number of Attributes: <" + atts.getLength() + + "> Line# <" + locator.getLineNumber() + ">"); + } + + /** + * Write startPrefixMapping tag along with prefix and uri when meet + * startPrefixMapping event. + * @throws IOException error happen when writing file. + */ + @Override + public void startPrefixMapping(String prefix, String uri) + throws SAXException { + println("startPrefixMapping...\n" + "prefix: <" + prefix + + "> uri: <" + uri + ">"); + } + /** + * Write outString to output file. + * @param outString string to be written. + * @throws SAXException + */ + private void println(String outString) throws SAXException { + try { + bWriter.write( outString, 0, outString.length()); + bWriter.newLine(); + } catch (IOException ex) { + throw new SAXException(WRITE_ERROR, ex); + } + } + + /** + * Close writer if it's initiated. + * @throws IOException if any I/O error when close writer. + */ + @Override + public void close() throws IOException { + if (bWriter != null) + bWriter.close(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java --- a/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package org.xml.sax.ptests; import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for JAXP SAX functional @@ -32,33 +32,15 @@ */ public class SAXTestConst { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; + public static final String XML_DIR = getPathByClassName(SAXTestConst.class, + ".." + FILE_SEP + "xmlfiles"); - /** - * Package name that separates by slash. - */ - public static final String PACKAGE_NAME = FILE_SEP + - SAXTestConst.class.getPackage().getName().replaceAll("[.]", FILE_SEP); /** - * Test base directory. Every package has its own test package directory. - */ - public static final String BASE_DIR - = System.getProperty("test.src", USER_DIR).replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP + ".."; - - /** - * Source XML file directory. + * Golden validation files directory. */ - public static final String XML_DIR = BASE_DIR + FILE_SEP + "xmlfiles" + FILE_SEP; - - /** - * Golden output file directory. We pre-define all expected output in golden - * output file. Test verifies whether the standard output is same as content - * of golden file. - */ - public static final String GOLDEN_DIR = XML_DIR + FILE_SEP + "out" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(SAXTestConst.class, + ".." + FILE_SEP + "xmlfiles" + FILE_SEP + "out"); } diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java --- a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,44 +22,21 @@ */ package test.auctionportal; -import static jaxp.library.JAXPTestUtilities.FILE_SEP; -import static jaxp.library.JAXPTestUtilities.USER_DIR; +import static jaxp.library.JAXPTestUtilities.getPathByClassName; /** * This is the Base test class provide basic support for Auction portal test. */ public class HiBidConstants { /** - * Current test directory. + * XML source file directory. */ - public static final String CLASS_DIR - = System.getProperty("test.classes", ".") + FILE_SEP; - - /** - * Package name that separates by slash. - */ - public static final String PACKAGE_NAME = FILE_SEP + - HiBidConstants.class.getPackage().getName().replaceAll("[.]", FILE_SEP); - + public static final String XML_DIR = getPathByClassName(HiBidConstants.class, "content"); /** - * Java source directory. - */ - public static final String SRC_DIR = System.getProperty("test.src", USER_DIR) - .replaceAll("\\" + System.getProperty("file.separator"), "/") - + PACKAGE_NAME + FILE_SEP; - - /** - * Source XML file directory. + * Golden validation files directory. */ - public static final String XML_DIR = SRC_DIR + "content" + FILE_SEP; - - /** - * Golden output file directory. - * We pre-define all expected output in golden output file. Test verifies - * whether the standard output is same as content of golden file. - */ - public static final String GOLDEN_DIR = SRC_DIR + "golden" + FILE_SEP; + public static final String GOLDEN_DIR = getPathByClassName(HiBidConstants.class, "golden"); /** * Name space for account operation. diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import org.w3c.dom.DOMErrorHandler; +import org.w3c.dom.DOMError; + +/** + * Error handler for recording DOM processing error. + */ +public class MyDOMErrorHandler implements DOMErrorHandler { + /** + * flag shows if there is any error. + */ + private volatile boolean errorOccured = false; + + /** + * Set errorOcurred to true when an error occurs. + * @param error The error object that describes the error. This object + * may be reused by the DOM implementation across multiple calls to + * the handleError method. + * @return true that processing may continue depending on. + */ + @Override + public boolean handleError (DOMError error) { + System.err.println( "ERROR" + error.getMessage()); + System.err.println( "ERROR" + error.getRelatedData()); + errorOccured = true; + return true; + } + + /** + * Showing if any error was handled. + * @return true if there is one or more error. + * false no error occurs. + */ + public boolean isError() { + return errorOccured; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import org.w3c.dom.ls.LSOutput; +import java.io.OutputStream; +import java.io.Writer; + +/** + * A Thread-safe LS output destination for DOM processing. LSOutput objects + * belong to the application. The DOM implementation will never modify them + * (though it may make copies and modify the copies, if necessary). + */ +public class MyDOMOutput implements LSOutput { + /** + * An attribute of a language and binding dependent type that represents a + * writable stream of bytes. + */ + private OutputStream bytestream; + + /** + * character encoding to use for the output. + */ + private String encoding; + + /** + * The system identifier. + */ + private String sysId; + + /** + * Writable stream to which 16-bit units can be output. + */ + private Writer writer; + + /** + * An attribute of a language and binding dependent type that represents a + * writable stream of bytes. + * + * @return a writable stream. + */ + @Override + public OutputStream getByteStream() { + return bytestream; + } + + /** + * An attribute of a language and binding dependent type that represents a + * writable stream to which 16-bit units can be output. + * + * @return writable stream instance. + */ + @Override + public Writer getCharacterStream() { + return writer; + } + + /** + * The character encoding to use for the output. + * + * @return the character encoding. + */ + @Override + public String getEncoding() { + return encoding; + } + + /** + * The system identifier for this output destination. + * + * @return system identifier. + */ + @Override + public String getSystemId() { + return sysId; + } + + /** + * Set writable stream of bytes. + * + * @param bs OutputStream instance + */ + @Override + public void setByteStream(OutputStream bs) { + bytestream = bs; + } + + /** + * Set 16 bits unit writable stream. + * + * @param cs a Writer instance + */ + @Override + public void setCharacterStream(Writer cs) { + writer = cs; + } + + /** + * Set character encoding to use for the output. + * + * @param encoding encoding set to the output + */ + @Override + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * Set the system identifier for the output. + * + * @param sysId system identifier string. + */ + @Override + public void setSystemId(String sysId) { + this.sysId = sysId; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * ErrorHandler for error handling. Set state if any method in error, warning + * or fatalError was called. + */ +public final class MyErrorHandler extends DefaultHandler { + /** + * Enumeration for ErrorHandler's state. + */ + private enum STATE { ERROR, FATAL, WARNING, NORMAL}; + + /** + * Set state as normal by default. + */ + private volatile STATE state = STATE.NORMAL; + + /** + * Keep exception for further investigation. + */ + private volatile SAXParseException exception; + + /** + * Save exception and set state to ERROR. + * @param e exception wrap error. + */ + @Override + public void error (SAXParseException e) { + state = STATE.ERROR; + exception = e; + } + + /** + * Save exception and set state to FATAL. + * @param e exception wrap error. + */ + @Override + public void fatalError (SAXParseException e) { + state = STATE.FATAL; + exception = e; + } + + /** + * Save exception and set state to WARNING. + * @param e exception wrap error. + */ + @Override + public void warning (SAXParseException e) { + state = STATE.WARNING; + exception = e; + } + + /** + * return ErrorHandle's state . + * @return true No error, fatalError and warning. + * false there is any error, fatalError or warning in processing. + */ + public boolean isAnyError() { + if (state != STATE.NORMAL) + System.out.println(exception); + return state != STATE.NORMAL; + } + + /** + * return whether fatalError is the only error. + * @return true fatalError is the only error. + * false there is no error, or other error besides fatalError. + */ + public boolean isFatalError() { + if (state == STATE.FATAL) + System.out.println(exception); + return state == STATE.FATAL; + } + +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package test.auctionportal; + +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.stream.Collectors; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.DefaultHandler; + +/** + * A SAX2 event handlers. + * This SAX2 ContentHandler receives callback event then print whole document + * that is parsed. + */ +public class XInclHandler extends DefaultHandler implements LexicalHandler { + /** + * Print writer. + */ + private final PrintWriter fOut; + + /** + * Canonical output. + */ + private volatile boolean fCanonical; + + /** + * Element depth. + */ + private volatile int fElementDepth; + + /** + * Sets whether output is canonical. + * + * @param canonical if the output is canonical format. + */ + public void setCanonical(boolean canonical) { + fCanonical = canonical; + } + + /** + * Sets the output stream for printing. + * @param stream OutputStream for message output. + * @param encoding File encoding for message output. + * @throws UnsupportedEncodingException if given encoding is an unsupported + * encoding name or invalid encoding name. + */ + public XInclHandler(OutputStream stream, String encoding) + throws UnsupportedEncodingException { + // At least set one encoding. + if (encoding == null) { + encoding = "UTF8"; + } + + fOut = new PrintWriter(new OutputStreamWriter(stream, encoding), false); + } + + /** + * Receive notification of the beginning of the document. Write the start + * document tag if it's not canonical mode. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void startDocument() throws SAXException { + fElementDepth = 0; + + if (!fCanonical) { + writeFlush(""); + } + } + + /** + * Receive notification of a processing instruction. + * @param target The processing instruction target. + * @param data The processing instruction data, or null if + * none is supplied. + * @exception SAXException Any SAX exception, possibly wrapping another + * exception. + */ + @Override + public void processingInstruction (String target, String data) + throws SAXException { + if (fElementDepth > 0) { + StringBuilder instruction = new StringBuilder(" 0) { + instruction.append(' ').append(data); + } + instruction.append("?>"); + writeFlush(instruction.toString()); + } + } + + /** + * Receive notification of the start of an element then write the normalized + * output to the file. + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param local The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param raw The qualified name (with prefix), or the + * empty string if qualified names are not available. + * @param attrs The attributes attached to the element. If + * there are no attributes, it shall be an empty + * Attributes object. + * @throws SAXException Any SAX exception, possibly wrapping another + * exception. + */ + @Override + public void startElement(String uri, String local, String raw, + Attributes attrs) throws SAXException { + fElementDepth++; + StringBuilder start = new StringBuilder().append('<').append(raw); + if (attrs != null) { + for (int i = 0; i < attrs.getLength(); i++) { + start.append(' ').append(attrs.getQName(i)).append("=\""). + append(normalizeAndPrint(attrs.getValue(i))).append('"'); + } + } + start.append('>'); + writeFlush(start.toString()); + } + + /** + * Receive notification of character data inside an element and write + * normalized characters to file. + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void characters(char ch[], int start, int length) + throws SAXException { + writeFlush(normalizeAndPrint(ch, start, length)); + } + + /** + * Receiving notification of ignorable whitespace in element content and + * writing normalized ignorable characters to file. + * @param ch The characters. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void ignorableWhitespace(char ch[], int start, int length) + throws SAXException { + characters(ch, start, length); + } + + /** + * Receive notification of the end of an element and print end element. + * + * @param uri The Namespace URI, or the empty string if the + * element has no Namespace URI or if Namespace + * processing is not being performed. + * @param local The local name (without prefix), or the + * empty string if Namespace processing is not being + * performed. + * @param raw The qualified name (with prefix), or the + * empty string if qualified names are not available. + * @throws org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void endElement(String uri, String local, String raw) + throws SAXException { + fElementDepth--; + writeFlush(""); + } + + /** + * Receive notification of a parser warning and print it out. + * @param ex The warning information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void warning(SAXParseException ex) throws SAXException { + printError("Warning", ex); + } + + /** + * Receive notification of a parser error and print it out. + * @param ex The error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + */ + @Override + public void error(SAXParseException ex) throws SAXException { + printError("Error", ex); + } + + /** + * Receive notification of a parser fatal error. Throw out fatal error + * following print fatal error message. + * @param ex The fatal error information encoded as an exception. + * @exception org.xml.sax.SAXException Any SAX exception, possibly + * wrapping another exception. + + */ + @Override + public void fatalError(SAXParseException ex) throws SAXException { + printError("Fatal Error", ex); + throw ex; + } + + /** + * Do nothing on start DTD. + * @param name The document type name. + * @param publicId The declared public identifier for the + * external DTD subset, or null if none was declared. + * @param systemId The declared system identifier for the + * external DTD subset, or null if none was declared. + * (Note that this is not resolved against the document + * base URI.) + * @exception SAXException The application may raise an + * exception. + */ + @Override + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + } + + /** + * Do nothing on end DTD. + * @exception SAXException The application may raise an exception. + */ + @Override + public void endDTD() throws SAXException { + } + + /** + * Do nothing on start entity. + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it is the + * external DTD subset, it will be "[dtd]". + * @exception SAXException The application may raise an exception. + */ + @Override + public void startEntity(String name) throws SAXException { + } + + /** + * Do nothing on end entity. + * @param name The name of the entity. If it is a parameter + * entity, the name will begin with '%', and if it is the + * external DTD subset, it will be "[dtd]". + * @exception SAXException The application may raise an exception. + */ + @Override + public void endEntity(String name) throws SAXException { + } + + /** + * Do nothing on start CDATA section. + * @exception SAXException The application may raise an exception. + */ + @Override + public void startCDATA() throws SAXException { + } + + /** + * Do nothing on end CDATA section. + * @exception SAXException The application may raise an exception. + */ + @Override + public void endCDATA() throws SAXException { + } + + /** + * Report an normalized XML comment when receive a comment in the document. + * + * @param ch An array holding the characters in the comment. + * @param start The starting position in the array. + * @param length The number of characters to use from the array. + * @exception SAXException The application may raise an exception. + */ + @Override + public void comment(char ch[], int start, int length) throws SAXException { + if (!fCanonical && fElementDepth > 0) { + writeFlush(""); + } + } + + /** + * Normalizes and prints the given string. + * @param s String to be normalized + */ + private String normalizeAndPrint(String s) { + return s.chars().mapToObj(c -> normalizeAndPrint((char)c)). + collect(Collectors.joining()); + } + + /** + * Normalizes and prints the given array of characters. + * @param ch The characters to be normalized. + * @param start The start position in the character array. + * @param length The number of characters to use from the + * character array. + */ + private String normalizeAndPrint(char[] ch, int offset, int length) { + return normalizeAndPrint(new String(ch, offset, length)); + } + + /** + * Normalizes given character. + * @param c char to be normalized. + */ + private String normalizeAndPrint(char c) { + switch (c) { + case '<': + return "<"; + case '>': + return ">"; + case '&': + return "&"; + case '"': + return """; + case '\r': + case '\n': + return fCanonical ? "&#" + Integer.toString(c) + ";" : String.valueOf(c); + default: + return String.valueOf(c); + } + } + + /** + * Prints the error message. + * @param type error type + * @param ex exception that need to be printed + */ + private void printError(String type, SAXParseException ex) { + System.err.print("[" + type + "] "); + String systemId = ex.getSystemId(); + if (systemId != null) { + int index = systemId.lastIndexOf('/'); + if (index != -1) + systemId = systemId.substring(index + 1); + System.err.print(systemId); + } + System.err.print(':' + ex.getLineNumber()); + System.err.print(':' + ex.getColumnNumber()); + System.err.println(": " + ex.getMessage()); + System.err.flush(); + } + + /** + * Write out and flush. + * @param out string to be written. + */ + private void writeFlush(String out) { + fOut.print(out); + fOut.flush(); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jaxws/.hgtags --- a/jaxws/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/jaxws/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -291,3 +291,4 @@ edc13d27dc871be57d7ca77eef77e6d04972fee2 jdk9-b43 2a03baa4d849818ff6d635f110c2813b12fc2326 jdk9-b44 e529374fbe526dbd668e5e98fc047b42b3bc6d33 jdk9-b45 +64ca52b0bda8028636e4ccafbe1107befcdda47d jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/.hgtags --- a/jdk/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 8c6ad41974f9ab6c33d544b088648314963f2a50 jdk9-b43 8cc4dc300041eb70a7a40e4b2431a8f4d4965ea4 jdk9-b44 9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45 +efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/make/gendata/GendataPolicyJars.gmk --- a/jdk/make/gendata/GendataPolicyJars.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/make/gendata/GendataPolicyJars.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -35,65 +35,62 @@ US_EXPORT_POLICY_JAR_DST := \ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar -ifneq ($(BUILD_CRYPTO), no) - - US_EXPORT_POLICY_JAR_LIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar - US_EXPORT_POLICY_JAR_UNLIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar +US_EXPORT_POLICY_JAR_LIMITED := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar +US_EXPORT_POLICY_JAR_UNLIMITED := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar - ifndef OPENJDK - # - # In past releases, Oracle JDK has had a separately downloadable set of - # policy files which has been a nightmare for deployment. - # - # Now if we're closed and limited (default for Oracle JDK), create - # an "unlimited_policy" directory that contains the unlimited policy - # files. It will be up to the user/deployer to make an informed choice - # as to whether they are legally entitled to use the unlimited policy - # file in their environment. Users/deployers simply need to overwrite - # the files. Consult README.txt (below) for more info. - # - UNLIMITED_POLICY_DIR := \ - $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/unlimited_policy - endif +ifndef OPENJDK + # + # In past releases, Oracle JDK has had a separately downloadable set of + # policy files which has been a nightmare for deployment. + # + # Now if we're closed and limited (default for Oracle JDK), create + # an "unlimited_policy" directory that contains the unlimited policy + # files. It will be up to the user/deployer to make an informed choice + # as to whether they are legally entitled to use the unlimited policy + # file in their environment. Users/deployers simply need to overwrite + # the files. Consult README.txt (below) for more info. + # + UNLIMITED_POLICY_DIR := \ + $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/unlimited_policy +endif - # - # TODO fix so that SetupArchive does not write files into SRCS - # then we don't need this extra copying - # - # NOTE: We currently do not place restrictions on our limited export - # policy. This was not a typo. This means we are shipping the same file - # for both limited and unlimited US_export_policy.jar. Only the local - # policy file currently has restrictions. - # - US_EXPORT_POLICY_JAR_SRC_DIR := \ - $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited - US_EXPORT_POLICY_JAR_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp +# +# TODO fix so that SetupArchive does not write files into SRCS +# then we don't need this extra copying +# +# NOTE: We currently do not place restrictions on our limited export +# policy. This was not a typo. This means we are shipping the same file +# for both limited and unlimited US_export_policy.jar. Only the local +# policy file currently has restrictions. +# +US_EXPORT_POLICY_JAR_SRC_DIR := \ + $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited +US_EXPORT_POLICY_JAR_TMP := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp - $(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/% +$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/% $(install-file) - US_EXPORT_POLICY_JAR_DEPS := \ - $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy +US_EXPORT_POLICY_JAR_DEPS := \ + $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy - $(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR, \ - $(US_EXPORT_POLICY_JAR_DEPS), \ - SRCS := $(US_EXPORT_POLICY_JAR_TMP), \ - SUFFIXES := .policy, \ - JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true)) +$(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR, \ + $(US_EXPORT_POLICY_JAR_DEPS), \ + SRCS := $(US_EXPORT_POLICY_JAR_TMP), \ + SUFFIXES := .policy, \ + JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \ + EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ + SKIP_METAINF := true)) - $(US_EXPORT_POLICY_JAR_LIMITED): \ - $(US_EXPORT_POLICY_JAR_UNLIMITED) - $(ECHO) $(LOG_INFO) \ - Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@) - $(install-file) +$(US_EXPORT_POLICY_JAR_LIMITED): \ + $(US_EXPORT_POLICY_JAR_UNLIMITED) + $(ECHO) $(LOG_INFO) \ + Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@) + $(install-file) - TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED) -endif +TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED) ifeq ($(UNLIMITED_CRYPTO), true) $(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED) @@ -119,57 +116,54 @@ LOCAL_POLICY_JAR_DST := \ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar -ifneq ($(BUILD_CRYPTO), no) +LOCAL_POLICY_JAR_LIMITED := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar +LOCAL_POLICY_JAR_UNLIMITED := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar - LOCAL_POLICY_JAR_LIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar - LOCAL_POLICY_JAR_UNLIMITED := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar +# +# TODO fix so that SetupArchive does not write files into SRCS +# then we don't need this extra copying +# +LOCAL_POLICY_JAR_LIMITED_TMP := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp +LOCAL_POLICY_JAR_UNLIMITED_TMP := \ + $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp + +$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \ + $(JDK_TOPDIR)/make/data/cryptopolicy/limited/% + $(install-file) + +$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \ + $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/% + $(install-file) - # - # TODO fix so that SetupArchive does not write files into SRCS - # then we don't need this extra copying - # - LOCAL_POLICY_JAR_LIMITED_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp - LOCAL_POLICY_JAR_UNLIMITED_TMP := \ - $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp +$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_LIMITED, \ + $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \ + $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \ + SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \ + SUFFIXES := .policy, \ + JAR := $(LOCAL_POLICY_JAR_LIMITED), \ + EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \ + SKIP_METAINF := true)) - $(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \ - $(JDK_TOPDIR)/make/data/cryptopolicy/limited/% - $(install-file) +$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_UNLIMITED, \ + $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \ + SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \ + SUFFIXES := .policy, \ + JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \ + EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ + SKIP_METAINF := true)) - $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \ - $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/% +TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED) + +ifndef OPENJDK + ifneq ($(UNLIMITED_CRYPTO), true) + $(UNLIMITED_POLICY_DIR)/README.txt: \ + $(JDK_TOPDIR)/make/closed/data/cryptopolicy/README.txt $(install-file) - $(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_LIMITED, \ - $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \ - $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \ - SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \ - SUFFIXES := .policy, \ - JAR := $(LOCAL_POLICY_JAR_LIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \ - SKIP_METAINF := true)) - - $(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_UNLIMITED, \ - $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \ - SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \ - SUFFIXES := .policy, \ - JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \ - EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \ - SKIP_METAINF := true)) - - TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED) - - ifndef OPENJDK - ifneq ($(UNLIMITED_CRYPTO), true) - $(UNLIMITED_POLICY_DIR)/README.txt: \ - $(JDK_TOPDIR)/make/closed/data/cryptopolicy/README.txt - $(install-file) - - TARGETS += $(UNLIMITED_POLICY_DIR)/README.txt - endif + TARGETS += $(UNLIMITED_POLICY_DIR)/README.txt endif endif diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java --- a/jdk/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,11 @@ private ClassLoaderHelper() {} /** + * Indicates, whether PATH env variable is allowed to contain quoted entries. + */ + static final boolean allowsQuotedPathElements = false; + + /** * Returns an alternate path name for the given file * such that if the original pathname did not exist, then the * file may be located at the alternate location. diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/share/classes/java/lang/Class.java --- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/Class.java Tue Jan 20 10:22:44 2015 -0800 @@ -149,7 +149,8 @@ * {@code getName}. If this {@code Class} object represents a * primitive type, this method returns the name of the primitive type. If * this {@code Class} object represents void this method returns - * "void". + * "void". If this {@code Class} object represents an array type, + * this method returns "class " followed by {@code getName}. * * @return a string representation of this class object. */ @@ -174,6 +175,12 @@ * occur in canonical order. If there are no type parameters, the * type parameter list is elided. * + * For an array type, the string starts with the type name, + * followed by an angle-bracketed comma-separated list of the + * type's type parameters, if any, followed by a sequence of + * {@code []} characters, one set of brackets per dimension of + * the array. + * *

Note that since information about the runtime representation * of a type is being generated, modifiers not present on the * originating source code or illegal on the originating source @@ -189,29 +196,39 @@ return toString(); } else { StringBuilder sb = new StringBuilder(); - - // Class modifiers are a superset of interface modifiers - int modifiers = getModifiers() & Modifier.classModifiers(); - if (modifiers != 0) { - sb.append(Modifier.toString(modifiers)); + Class component = this; + int arrayDepth = 0; + + if (isArray()) { + do { + arrayDepth++; + component = component.getComponentType(); + } while (component.isArray()); + sb.append(component.getName()); + } else { + // Class modifiers are a superset of interface modifiers + int modifiers = getModifiers() & Modifier.classModifiers(); + if (modifiers != 0) { + sb.append(Modifier.toString(modifiers)); + sb.append(' '); + } + + if (isAnnotation()) { + sb.append('@'); + } + if (isInterface()) { // Note: all annotation types are interfaces + sb.append("interface"); + } else { + if (isEnum()) + sb.append("enum"); + else + sb.append("class"); + } sb.append(' '); - } - - if (isAnnotation()) { - sb.append('@'); + sb.append(getName()); } - if (isInterface()) { // Note: all annotation types are interfaces - sb.append("interface"); - } else { - if (isEnum()) - sb.append("enum"); - else - sb.append("class"); - } - sb.append(' '); - sb.append(getName()); - - TypeVariable[] typeparms = getTypeParameters(); + + TypeVariable[] typeparms = component.getTypeParameters(); if (typeparms.length > 0) { boolean first = true; sb.append('<'); @@ -224,6 +241,9 @@ sb.append('>'); } + for (int i = 0; i < arrayDepth; i++) + sb.append("[]"); + return sb.toString(); } } diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/share/classes/java/lang/ClassLoader.java --- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1747,35 +1747,54 @@ private static String usr_paths[]; private static String sys_paths[]; - private static String[] initializePath(String propname) { - String ldpath = System.getProperty(propname, ""); - String ps = File.pathSeparator; - int ldlen = ldpath.length(); - int i, j, n; - // Count the separators in the path - i = ldpath.indexOf(ps); - n = 0; - while (i >= 0) { - n++; - i = ldpath.indexOf(ps, i + 1); + private static String[] initializePath(String propName) { + String ldPath = System.getProperty(propName, ""); + int ldLen = ldPath.length(); + char ps = File.pathSeparatorChar; + int psCount = 0; + + if (ClassLoaderHelper.allowsQuotedPathElements && + ldPath.indexOf('\"') >= 0) { + // First, remove quotes put around quoted parts of paths. + // Second, use a quotation mark as a new path separator. + // This will preserve any quoted old path separators. + char[] buf = new char[ldLen]; + int bufLen = 0; + for (int i = 0; i < ldLen; ++i) { + char ch = ldPath.charAt(i); + if (ch == '\"') { + while (++i < ldLen && + (ch = ldPath.charAt(i)) != '\"') { + buf[bufLen++] = ch; + } + } else { + if (ch == ps) { + psCount++; + ch = '\"'; + } + buf[bufLen++] = ch; + } + } + ldPath = new String(buf, 0, bufLen); + ldLen = bufLen; + ps = '\"'; + } else { + for (int i = ldPath.indexOf(ps); i >= 0; + i = ldPath.indexOf(ps, i + 1)) { + psCount++; + } } - // allocate the array of paths - n :'s = n + 1 path elements - String[] paths = new String[n + 1]; - - // Fill the array with paths from the ldpath - n = i = 0; - j = ldpath.indexOf(ps); - while (j >= 0) { - if (j - i > 0) { - paths[n++] = ldpath.substring(i, j); - } else if (j - i == 0) { - paths[n++] = "."; - } - i = j + 1; - j = ldpath.indexOf(ps, i); + String[] paths = new String[psCount + 1]; + int pathStart = 0; + for (int j = 0; j < psCount; ++j) { + int pathEnd = ldPath.indexOf(ps, pathStart); + paths[j] = (pathStart < pathEnd) ? + ldPath.substring(pathStart, pathEnd) : "."; + pathStart = pathEnd + 1; } - paths[n] = ldpath.substring(i, ldlen); + paths[psCount] = (pathStart < ldLen) ? + ldPath.substring(pathStart, ldLen) : "."; return paths; } diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/share/classes/java/lang/reflect/Executable.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -588,22 +588,29 @@ return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Executable root = getRoot(); - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - getAnnotationBytes(), - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Executable root = getRoot(); + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + getAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass() + ); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } /** diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/share/classes/java/lang/reflect/Field.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1139,21 +1139,28 @@ return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Field root = this.root; - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, - sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Field root = this.root; + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + annotations, + sun.misc.SharedSecrets.getJavaLangAccess() + .getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } private native byte[] getTypeAnnotationBytes0(); diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/share/classes/java/util/Formatter.java --- a/jdk/src/java.base/share/classes/java/util/Formatter.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/Formatter.java Tue Jan 20 10:22:44 2015 -0800 @@ -1835,7 +1835,7 @@ *

The maximum number of arguments is limited by the maximum dimension of a * Java array as defined by * The Java™ Virtual Machine Specification. - * If the argument index is does not correspond to an + * If the argument index does not correspond to an * available argument, then a {@link MissingFormatArgumentException} is thrown. * *

If there are more arguments than format specifiers, the extra arguments diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java --- a/jdk/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,11 @@ private ClassLoaderHelper() {} /** + * Indicates, whether PATH env variable is allowed to contain quoted entries. + */ + static final boolean allowsQuotedPathElements = false; + + /** * Returns an alternate path name for the given file * such that if the original pathname did not exist, then the * file may be located at the alternate location. diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java --- a/jdk/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,11 @@ private ClassLoaderHelper() {} /** + * Indicates, whether PATH env variable is allowed to contain quoted entries. + */ + static final boolean allowsQuotedPathElements = true; + + /** * Returns an alternate path name for the given file * such that if the original pathname did not exist, then the * file may be located at the alternate location. diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/Code.java --- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/Code.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/Code.java Tue Jan 20 10:22:44 2015 -0800 @@ -103,7 +103,7 @@ case HTTP_UNAVAILABLE: return " Service Unavailable"; case HTTP_GATEWAY_TIMEOUT: return " Gateway Timeout"; case HTTP_VERSION: return " HTTP Version Not Supported"; - default: return ""; + default: return " "; } } } diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/test/com/sun/net/httpserver/MissingTrailingSpace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/net/httpserver/MissingTrailingSpace.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8068795 + * @summary HttpServer missing tailing space for some response codes + * @author lev.priima@oracle.com + */ + +import java.net.InetSocketAddress; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class MissingTrailingSpace { + + private static final int noMsgCode = 207; + private static final String someContext = "/context"; + + public static void main(String[] args) throws Exception { + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + try { + server.setExecutor(Executors.newFixedThreadPool(1)); + server.createContext(someContext, new HttpHandler() { + @Override + public void handle(HttpExchange msg) { + try { + try { + msg.sendResponseHeaders(noMsgCode, -1); + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } finally { + msg.close(); + } + } + }); + server.start(); + System.out.println("Server started at port " + + server.getAddress().getPort()); + + runRawSocketHttpClient("localhost", server.getAddress().getPort()); + } finally { + ((ExecutorService)server.getExecutor()).shutdown(); + server.stop(0); + } + System.out.println("Server finished."); + } + + static void runRawSocketHttpClient(String hostname, int port) + throws Exception + { + Socket socket = null; + PrintWriter writer = null; + BufferedReader reader = null; + final String CRLF = "\r\n"; + try { + socket = new Socket(hostname, port); + writer = new PrintWriter(new OutputStreamWriter( + socket.getOutputStream())); + System.out.println("Client connected by socket: " + socket); + + writer.print("GET " + someContext + "/ HTTP/1.1" + CRLF); + writer.print("User-Agent: Java/" + + System.getProperty("java.version") + + CRLF); + writer.print("Host: " + hostname + CRLF); + writer.print("Accept: */*" + CRLF); + writer.print("Connection: keep-alive" + CRLF); + writer.print(CRLF); // Important, else the server will expect that + // there's more into the request. + writer.flush(); + System.out.println("Client wrote rquest to socket: " + socket); + + reader = new BufferedReader(new InputStreamReader( + socket.getInputStream())); + System.out.println("Client start reading from server:" ); + String line = reader.readLine(); + if ( !line.endsWith(" ") ) { + throw new RuntimeException("respond to unknown code " + + noMsgCode + + " doesn't return space at the end of the first header.\n" + + "Should be: " + "\"" + line + " \"" + + ", but returns: " + "\"" + line + "\"."); + } + for (; line != null; line = reader.readLine()) { + if (line.isEmpty()) { + break; + } + System.out.println("\"" + line + "\""); + } + System.out.println("Client finished reading from server" ); + } finally { + if (reader != null) + try { + reader.close(); + } catch (IOException logOrIgnore) { + logOrIgnore.printStackTrace(); + } + if (writer != null) { + writer.close(); + } + if (socket != null) { + try { + socket.close(); + } catch (IOException logOrIgnore) { + logOrIgnore.printStackTrace(); + } + } + } + System.out.println("Client finished." ); + } +} + diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/test/java/lang/Class/GenericStringTest.java --- a/jdk/test/java/lang/Class/GenericStringTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/test/java/lang/Class/GenericStringTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,10 +34,29 @@ @ExpectedGenericString("public class GenericStringTest") public class GenericStringTest { - public static void main(String... args){ + public Map[] mixed = null; + public Map[][] mixed2 = null; + + public static void main(String... args) throws ReflectiveOperationException { int failures = 0; + String[][] nested = {{""}}; + int[][] intArray = {{1}}; + failures += checkToGenericString(int.class, "int"); + failures += checkToGenericString(void.class, "void"); + failures += checkToGenericString(args.getClass(), "java.lang.String[]"); + failures += checkToGenericString(nested.getClass(), "java.lang.String[][]"); + failures += checkToGenericString(intArray.getClass(), "int[][]"); + failures += checkToGenericString(java.util.Map.class, "public abstract interface java.util.Map"); + + Field f = GenericStringTest.class.getDeclaredField("mixed"); + // The expected value includes "" rather than + // "<...String,...Integer>" since the Class object rather than + // Type objects is being queried. + failures += checkToGenericString(f.getType(), "java.util.Map[]"); + f = GenericStringTest.class.getDeclaredField("mixed2"); + failures += checkToGenericString(f.getType(), "java.util.Map[][]"); Class[] types = { GenericStringTest.class, diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/test/java/lang/ClassLoader/LibraryPathProperty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/ClassLoader/LibraryPathProperty.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8067951 + * @summary Unit test for internal ClassLoader#initializePath(). + * Quoted entries should get unquoted on Windows. + * Empty entries should be replaced with dot. + * @library /lib/testlibrary + * @build jdk.testlibrary.Platform + * @run main LibraryPathProperty + */ + +import java.lang.reflect.Method; +import java.io.File; +import java.util.Arrays; +import jdk.testlibrary.Platform; + +public class LibraryPathProperty { + + static final String propName = "test.property.name"; + static final String SP = File.pathSeparator; + static Method method; + + public static void main(String[] args) throws Throwable { + method = ClassLoader.class + .getDeclaredMethod("initializePath", + String.class); + method.setAccessible(true); + + test("", "."); + test(SP, ".", "."); + test("a" + SP, "a", "."); + test(SP + "b", ".", "b"); + test("a" + SP + SP + "b", "a", ".", "b"); + + if (Platform.isWindows()) { + // on Windows parts of paths may be quoted + test("\"\"", "."); + test("\"\"" + SP, ".", "."); + test(SP + "\"\"", ".", "."); + test("a" + SP + "\"b\"" + SP, "a", "b", "."); + test(SP + "\"a\"" + SP + SP + "b", ".", "a", ".", "b"); + test("\"a\"" + SP + "\"b\"", "a", "b"); + test("\"/a/\"b" + SP + "c", "/a/b", "c"); + test("\"/a;b\"" + SP + "c", "/a;b", "c"); + test("\"/a:b\"" + SP + "c", "/a:b", "c"); + test("\"/a" + SP + "b\"" + SP + "c", "/a" + SP + "b", "c"); + test("/\"a\"\";\"\"b\"" + SP + "\"c\"", "/a;b", "c"); + test("/\"a:\"b" + SP + "c", "/a:b", "c"); + } + } + + static void test(String s, String... expected) throws Throwable { + System.setProperty(propName, s); + String[] res = (String[])method.invoke(null, propName); + if (!Arrays.asList(res).equals(Arrays.asList(expected))) { + throw new RuntimeException("Parsing [" + s + "] " + + " result " + Arrays.asList(res) + + " doesn't match " + Arrays.asList(expected)); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java --- a/jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -48,14 +48,7 @@ static final File tmpFolder = new File(testClassesDir); static { - String javaHome = System.getProperty("java.home"); - if (javaHome.endsWith("jre")) { - int index = javaHome.lastIndexOf(slash); - if (index != -1) - javaHome = javaHome.substring(0, index); - } - - jar = javaHome + slash + "bin" + slash + "jar"; + jar = System.getProperty("java.home") + slash + "bin" + slash + "jar"; } public static void main(String[] args) throws Exception { diff -r 6b55dd30a0ba -r 0388b3b63648 jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java --- a/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Thu Jan 15 19:23:49 2015 -0800 +++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Tue Jan 20 10:22:44 2015 -0800 @@ -78,7 +78,6 @@ * URLClassLoader. Each request to the HTTP server is recorded to ensure * only the correct amount of requests are being made. * - * Note: Needs jdk/lib/tools.jar in the classpath to compile and run. */ public class Basic { @@ -160,14 +159,7 @@ static String jar; static { - String javaHome = System.getProperty("java.home"); - if (javaHome.endsWith("jre")) { - int index = javaHome.lastIndexOf(slash); - if (index != -1) - javaHome = javaHome.substring(0, index); - } - - jar = javaHome + slash+ "bin" + slash + "jar"; + jar = System.getProperty("java.home") + slash+ "bin" + slash + "jar"; } /* create the index */ diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/.hgtags --- a/langtools/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -288,3 +288,4 @@ 6a06008aec10d32898ca665685f531c681b28f5f jdk9-b43 de2ce70d907c9f227b802cea29285bece5194cd5 jdk9-b44 73bbdcf236b297a0c1b8875f2eeba65eaf7ade60 jdk9-b45 +e272d9be5f90edb6bb6b40f7816ec85eec0f5dc2 jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/make/Tools.gmk --- a/langtools/make/Tools.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/make/Tools.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -40,6 +40,7 @@ ADD_JAVAC_FLAGS := -Xprefer:source, \ SRC := $(LANGTOOLS_TOPDIR)/make/tools, \ INCLUDES := compileproperties propertiesparser, \ + COPY := .properties, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes)) all: $(BUILD_TOOLS_LANGTOOLS) diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/make/gensrc/Gensrc-jdk.compiler.gmk --- a/langtools/make/gensrc/Gensrc-jdk.compiler.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/make/gensrc/Gensrc-jdk.compiler.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -25,19 +25,19 @@ include GensrcCommon.gmk -$(eval $(call SetupVersionProperties,JAVAC_VERSION,\ +$(eval $(call SetupVersionProperties,JAVAC_VERSION, \ com/sun/tools/javac/resources/version.properties)) -$(eval $(call SetupVersionProperties,JAVAH_VERSION,\ +$(eval $(call SetupVersionProperties,JAVAH_VERSION, \ com/sun/tools/javah/resources/version.properties)) -$(eval $(call SetupVersionProperties,JAVAP_VERSION,\ +$(eval $(call SetupVersionProperties,JAVAP_VERSION, \ com/sun/tools/javap/resources/version.properties)) -$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES,\ +$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \ $(JAVAC_VERSION) $(JAVAH_VERSION) $(JAVAP_VERSION))) -$(eval $(call SetupParseProperties,PARSE_PROPERTIES,\ +$(eval $(call SetupParseProperties,PARSE_PROPERTIES, \ com/sun/tools/javac/resources/compiler.properties)) all: $(COMPILE_PROPERTIES) $(PARSE_PROPERTIES) diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/make/gensrc/GensrcCommon.gmk --- a/langtools/make/gensrc/GensrcCommon.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/make/gensrc/GensrcCommon.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -63,7 +63,8 @@ # Param 2 - Extra properties files to process define SetupCompileProperties # Lookup the properties that need to be compiled into resource bundles. - PROPSOURCES := $2 $$(shell $(FIND) $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes -name "*.properties") + PROPSOURCES := $2 \ + $$(shell $(FIND) $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes -name "*.properties") # Convert .../src//share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties # to .../langtools/gensrc//com/sun/tools/javac/resources/javac_zh_CN.java @@ -74,7 +75,7 @@ $$(patsubst %.properties, %.java, \ $$(subst /share/classes,, $$(PROPSOURCES)))) - # Generate the package dirs for the tobe generated java files. Sort to remove + # Generate the package dirs for the to be generated java files. Sort to remove # duplicates. PROPDIRS := $$(sort $$(dir $$(PROPJAVAS))) @@ -88,8 +89,8 @@ # Now setup the rule for the generation of the resource bundles. $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the_props: $$(PROPSOURCES) - $(FIND) $$(@D) -name "*.java" $(FIND_DELETE) $(MKDIR) -p $$(@D) $$(PROPDIRS) + $(FIND) $$(@D) -name "*.java" -a ! -name "*Properties.java" $(FIND_DELETE) $(ECHO) Compiling $$(words $$(PROPSOURCES)) properties into resource bundles for $(MODULE) $(TOOL_COMPILEPROPS_CMD) $$(PROPCMDLINE) $(TOUCH) $$@ @@ -102,11 +103,11 @@ # Param 1 - Variable to add targets to # Param 2 - Extra properties files to process define SetupParseProperties - #property file to generate - PARSEPROPSOURCES := $$(foreach var,$2,$$(addsuffix $$(var),$(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/)) + # property files to process + PARSEPROPSOURCES := $$(addprefix $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/, $2) - PARSEPROPALLDIRS := $$(patsubst $(LANGTOOLS_TOPDIR)/src/%, \ - $(SUPPORT_OUTPUTDIR)/gensrc/%, \ + PARSEPROPALLDIRS := $$(patsubst $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/%, \ + $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/%, \ $$(dir $$(PARSEPROPSOURCES))) PARSEPROPDIRS := $$(sort $$(PARSEPROPALLDIRS)) @@ -114,11 +115,11 @@ PARSEPROPCMDLINE := $$(subst _SPACE_, $$(SPACE), \ $$(join $$(foreach var,$$(PARSEPROPSOURCES),$$(addprefix -compile_SPACE_,$$(var))), \ $$(addprefix _SPACE_, $$(PARSEPROPALLDIRS)))) - + # Now setup the rule for the generation of the resource bundles. $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the_parsed_props: $(PARSEPROPSOURCES) - $(CP) -r $(LANGTOOLS_TOPDIR)/make/tools/propertiesparser/resources $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes/propertiesparser/resources $(MKDIR) -p $$(@D) $$(PARSEPROPDIRS) + $(FIND) $$(@D) -name "*Properties.java" $(FIND_DELETE) $(ECHO) Parsing $$(words $$(PARSEPROPSOURCES)) properties into enum-like class for $(MODULE) $(TOOL_PARSEPROPS_CMD) $$(PARSEPROPCMDLINE) $(TOUCH) $$@ diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ # questions. # -dc.anchor.already.defined = anchor already defined: {0} +dc.anchor.already.defined = anchor already defined: "{0}" dc.anchor.value.missing = no value given for anchor dc.attr.lacks.value = attribute lacks value dc.attr.not.number = attribute value is not a number diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -98,6 +98,7 @@ import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; @@ -924,12 +925,7 @@ try { switch (kind) { case ERROR: - boolean prev = log.multipleErrors; - try { - log.error(pos, "proc.messager", msg.toString()); - } finally { - log.multipleErrors = prev; - } + log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString()); break; case WARNING: diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Tue Jan 20 10:22:44 2015 -0800 @@ -74,8 +74,7 @@ WRONG_MTHS(Category.OVERLOAD, KindName.METHOD), WRONG_MTH(Category.OVERLOAD, KindName.METHOD), ABSENT_MTH(Category.OVERLOAD, KindName.METHOD), - ABSENT_TYP(Category.OVERLOAD, KindName.CLASS), - WRONG_STATICNESS(Category.OVERLOAD, KindName.METHOD); + ABSENT_TYP(Category.OVERLOAD, KindName.CLASS); // There are essentially two "levels" to the Kind datatype. // The first is a totally-ordered set of categories of diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Jan 20 10:22:44 2015 -0800 @@ -1175,6 +1175,16 @@ return v.visitClassSymbol(this, p); } + public void markAbstractIfNeeded(Types types) { + if (types.enter.getEnv(this) != null && + (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym && + (flags() & (FINAL | ABSTRACT)) == 0) { + if (types.firstUnimplementedAbstract(this) != null) + // add the ABSTRACT flag to an enum + flags_field |= ABSTRACT; + } + } + /**Resets the Symbol into the state good for next round of annotation processing.*/ public void reset() { kind = TYP; diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Tue Jan 20 10:22:44 2015 -0800 @@ -48,6 +48,7 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Scope.*; +import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; import static com.sun.tools.javac.code.Symbol.*; import static com.sun.tools.javac.code.Type.*; import static com.sun.tools.javac.code.TypeTag.*; @@ -82,6 +83,7 @@ final JavacMessages messages; final Names names; final boolean allowObjectToPrimitiveCast; + final boolean allowDefaultMethods; final Check chk; final Enter enter; JCDiagnostic.Factory diags; @@ -105,6 +107,7 @@ names = Names.instance(context); Source source = Source.instance(context); allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); + allowDefaultMethods = source.allowDefaultMethods(); chk = Check.instance(context); enter = Enter.instance(context); capturedName = names.fromString(""); @@ -805,13 +808,13 @@ return true; } - // Generally, if 's' is a type variable, recur on lower bound; but + // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but // for inference variables and intersections, we need to keep 's' // (see JLS 4.10.2 for intersections and 18.2.3 for inference vars) if (!t.hasTag(UNDETVAR) && !t.isCompound()) { // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s Type lower = cvarLowerBound(wildLowerBound(s)); - if (s != lower) + if (s != lower && !lower.hasTag(BOT)) return isSubtype(capture ? capture(t) : t, lower, false); } @@ -2775,6 +2778,58 @@ // + /** Return first abstract member of class `sym'. + */ + public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) { + try { + return firstUnimplementedAbstractImpl(sym, sym); + } catch (CompletionFailure ex) { + chk.completionError(enter.getEnv(sym).tree.pos(), ex); + return null; + } + } + //where: + private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) { + MethodSymbol undef = null; + // Do not bother to search in classes that are not abstract, + // since they cannot have abstract members. + if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { + Scope s = c.members(); + for (Symbol sym : s.getSymbols(NON_RECURSIVE)) { + if (sym.kind == MTH && + (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) { + MethodSymbol absmeth = (MethodSymbol)sym; + MethodSymbol implmeth = absmeth.implementation(impl, this, true); + if (implmeth == null || implmeth == absmeth) { + //look for default implementations + if (allowDefaultMethods) { + MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head; + if (prov != null && prov.overrides(absmeth, impl, this, true)) { + implmeth = prov; + } + } + } + if (implmeth == null || implmeth == absmeth) { + undef = absmeth; + break; + } + } + } + if (undef == null) { + Type st = supertype(c.type); + if (st.hasTag(CLASS)) + undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym); + } + for (List l = interfaces(c.type); + undef == null && l.nonEmpty(); + l = l.tail) { + undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym); + } + } + return undef; + } + + //where public List interfaceCandidates(Type site, MethodSymbol ms) { Filter filter = new MethodFilter(ms, site); diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Jan 20 10:22:44 2015 -0800 @@ -2640,8 +2640,7 @@ try { refResult = rs.resolveMemberReference(localEnv, that, that.expr.type, that.name, argtypes, typeargtypes, referenceCheck, - resultInfo.checkContext.inferenceContext(), - resultInfo.checkContext.deferredAttrContext().mode); + resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser); } finally { resultInfo.checkContext.inferenceContext().rollback(saved_undet); } @@ -2659,9 +2658,8 @@ case WRONG_MTHS: case AMBIGUOUS: case HIDDEN: + case MISSING_ENCL: case STATICERR: - case MISSING_ENCL: - case WRONG_STATICNESS: targetError = true; break; default: @@ -2722,15 +2720,6 @@ return; } - if (that.sym.isStatic() && !TreeInfo.isStaticSelector(that.expr, names) && - !that.kind.isUnbound()) { - //no static bound mrefs - log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), - diags.fragment("static.bound.mref")); - result = that.type = types.createErrorType(currentTarget); - return; - } - if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) { // Check that super-qualified symbols are not abstract (JLS) rs.checkNonAbstract(that.pos(), that.sym); @@ -4199,6 +4188,8 @@ chk.validate(tree.implementing, env); } + c.markAbstractIfNeeded(types); + // If this is a non-abstract class, check that it has no abstract // methods or unimplemented methods of an implemented interface. if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) { diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Jan 20 10:22:44 2015 -0800 @@ -2019,69 +2019,15 @@ * @param c The class. */ void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) { - try { - MethodSymbol undef = firstUndef(c, c); - if (undef != null) { - if ((c.flags() & ENUM) != 0 && - types.supertype(c.type).tsym == syms.enumSym && - (c.flags() & FINAL) == 0) { - // add the ABSTRACT flag to an enum - c.flags_field |= ABSTRACT; - } else { - MethodSymbol undef1 = - new MethodSymbol(undef.flags(), undef.name, - types.memberType(c.type, undef), undef.owner); - log.error(pos, "does.not.override.abstract", - c, undef1, undef1.location()); - } - } - } catch (CompletionFailure ex) { - completionError(pos, ex); + MethodSymbol undef = types.firstUnimplementedAbstract(c); + if (undef != null) { + MethodSymbol undef1 = + new MethodSymbol(undef.flags(), undef.name, + types.memberType(c.type, undef), undef.owner); + log.error(pos, "does.not.override.abstract", + c, undef1, undef1.location()); } } -//where - /** Return first abstract member of class `c' that is not defined - * in `impl', null if there is none. - */ - private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) { - MethodSymbol undef = null; - // Do not bother to search in classes that are not abstract, - // since they cannot have abstract members. - if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { - Scope s = c.members(); - for (Symbol sym : s.getSymbols(NON_RECURSIVE)) { - if (sym.kind == MTH && - (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) { - MethodSymbol absmeth = (MethodSymbol)sym; - MethodSymbol implmeth = absmeth.implementation(impl, types, true); - if (implmeth == null || implmeth == absmeth) { - //look for default implementations - if (allowDefaultMethods) { - MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head; - if (prov != null && prov.overrides(absmeth, impl, types, true)) { - implmeth = prov; - } - } - } - if (implmeth == null || implmeth == absmeth) { - undef = absmeth; - break; - } - } - } - if (undef == null) { - Type st = types.supertype(c.type); - if (st.hasTag(CLASS)) - undef = firstUndef(impl, (ClassSymbol)st.tsym); - } - for (List l = types.interfaces(c.type); - undef == null && l.nonEmpty(); - l = l.tail) { - undef = firstUndef(impl, (ClassSymbol)l.head.tsym); - } - } - return undef; - } void checkNonCyclicDecl(JCClassDecl tree) { CycleChecker cc = new CycleChecker(); diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Jan 20 10:22:44 2015 -0800 @@ -27,6 +27,9 @@ import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.comp.Resolve.ResolveError; +import com.sun.tools.javac.resources.CompilerProperties; +import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.DefinedBy.Api; @@ -37,6 +40,7 @@ import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import java.util.ArrayList; @@ -786,16 +790,22 @@ JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; Symbol lookupSym = - rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type, - tree.name, argtypes.toList(), inferenceContext); + rs.resolveMemberReference(localEnv, mref2, exprTree.type, + tree.name, argtypes.toList(), List.nil(), rs.arityMethodCheck, + inferenceContext, rs.structuralReferenceChooser).fst; switch (lookupSym.kind) { - //note: as argtypes are erroneous types, type-errors must - //have been caused by arity mismatch - case ABSENT_MTH: case WRONG_MTH: case WRONG_MTHS: - case WRONG_STATICNESS: - checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref")); + //note: as argtypes are erroneous types, type-errors must + //have been caused by arity mismatch + checkContext.report(tree, diags.fragment(Fragments.IncompatibleArgTypesInMref)); + break; + case ABSENT_MTH: + case STATICERR: + //if no method found, or method found with wrong staticness, report better message + checkContext.report(tree, ((ResolveError)lookupSym).getDiagnostic(DiagnosticType.FRAGMENT, + tree, exprTree.type.tsym, exprTree.type, tree.name, argtypes.toList(), List.nil())); + break; } } } diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Jan 20 10:22:44 2015 -0800 @@ -263,7 +263,7 @@ @Override public void visitLambda(JCLambda tree) { LambdaTranslationContext localContext = (LambdaTranslationContext)context; - MethodSymbol sym = (MethodSymbol)localContext.translatedSym; + MethodSymbol sym = localContext.translatedSym; MethodType lambdaType = (MethodType) sym.type; { @@ -875,11 +875,9 @@ */ private JCExpression expressionInvoke(VarSymbol rcvr) { JCExpression qualifier = - tree.sym.isStatic() ? - make.Type(tree.sym.owner.type) : - (rcvr != null) ? - makeReceiver(rcvr) : - tree.getQualifierExpression(); + (rcvr != null) ? + makeReceiver(rcvr) : + tree.getQualifierExpression(); //create the qualifier expression JCFieldAccess select = make.Select(qualifier, tree.sym.name); @@ -1755,7 +1753,7 @@ Map> translatedSymbols; /** the synthetic symbol for the method hoisting the translated lambda */ - Symbol translatedSym; + MethodSymbol translatedSym; List syntheticParams; @@ -1997,6 +1995,7 @@ //compute synthetic params ListBuffer params = new ListBuffer<>(); + ListBuffer parameterSymbols = new ListBuffer<>(); // The signature of the method is augmented with the following // synthetic parameters: @@ -2005,19 +2004,16 @@ // 2) enclosing locals captured by the lambda expression for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) { params.append(make.VarDef((VarSymbol) thisSym, null)); - } - if (methodReferenceReceiver != null) { - params.append(make.VarDef( - make.Modifiers(PARAMETER|FINAL), - names.fromString("$rcvr$"), - make.Type(methodReferenceReceiver.type), - null)); + parameterSymbols.append((VarSymbol) thisSym); } for (Symbol thisSym : getSymbolMap(PARAM).values()) { params.append(make.VarDef((VarSymbol) thisSym, null)); + parameterSymbols.append((VarSymbol) thisSym); } syntheticParams = params.toList(); + translatedSym.params = parameterSymbols.toList(); + // Compute and set the lambda name translatedSym.name = isSerializable() ? serializedLambdaName() diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Jan 20 10:22:44 2015 -0800 @@ -25,7 +25,6 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.tools.javac.api.Formattable.LocalizedString; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Scope.WriteableScope; @@ -40,6 +39,7 @@ import com.sun.tools.javac.comp.Infer.FreeTypeListener; import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template; +import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.main.Option; import com.sun.tools.javac.tree.*; @@ -65,6 +65,7 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.BLOCK; +import static com.sun.tools.javac.code.Flags.STATIC; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.TypeTag.*; @@ -105,15 +106,10 @@ context.put(resolveKey, this); syms = Symtab.instance(context); - varNotFound = new - SymbolNotFoundError(ABSENT_VAR); - methodNotFound = new - SymbolNotFoundError(ABSENT_MTH); - methodWithCorrectStaticnessNotFound = new - SymbolNotFoundError(WRONG_STATICNESS, - "method found has incorrect staticness"); - typeNotFound = new - SymbolNotFoundError(ABSENT_TYP); + varNotFound = new SymbolNotFoundError(ABSENT_VAR); + methodNotFound = new SymbolNotFoundError(ABSENT_MTH); + typeNotFound = new SymbolNotFoundError(ABSENT_TYP); + referenceNotFound = new ReferenceLookupResult(methodNotFound, null); names = Names.instance(context); log = Log.instance(context); @@ -145,9 +141,11 @@ */ private final SymbolNotFoundError varNotFound; private final SymbolNotFoundError methodNotFound; - private final SymbolNotFoundError methodWithCorrectStaticnessNotFound; private final SymbolNotFoundError typeNotFound; + /** empty reference lookup result */ + private final ReferenceLookupResult referenceNotFound; + public static Resolve instance(Context context) { Resolve instance = context.get(resolveKey); if (instance == null) @@ -2680,69 +2678,16 @@ List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) { - ReferenceLookupHelper result; if (!name.equals(names.init)) { //method reference - result = - new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); + return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); + } else if (site.hasTag(ARRAY)) { + //array constructor reference + return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); } else { - if (site.hasTag(ARRAY)) { - //array constructor reference - result = - new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } else { - //class constructor reference - result = - new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } + //class constructor reference + return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); } - return result; - } - - Symbol resolveMemberReferenceByArity(Env env, - JCMemberReference referenceTree, - Type site, - Name name, - List argtypes, - InferenceContext inferenceContext) { - - boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names); - site = types.capture(site); - - ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( - referenceTree, site, name, argtypes, null, VARARITY); - //step 1 - bound lookup - Env boundEnv = env.dup(env.tree, env.info.dup()); - Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, - arityMethodCheck, boundLookupHelper); - if (isStaticSelector && - !name.equals(names.init) && - !boundSym.isStatic() && - !boundSym.kind.isOverloadError()) { - boundSym = methodNotFound; - } - - //step 2 - unbound lookup - Symbol unboundSym = methodNotFound; - ReferenceLookupHelper unboundLookupHelper = null; - Env unboundEnv = env.dup(env.tree, env.info.dup()); - if (isStaticSelector) { - unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); - unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, - arityMethodCheck, unboundLookupHelper); - if (unboundSym.isStatic() && - !unboundSym.kind.isOverloadError()) { - unboundSym = methodNotFound; - } - } - - //merge results - Symbol bestSym = choose(boundSym, unboundSym); - env.info.pendingResolutionPhase = bestSym == unboundSym ? - unboundEnv.info.pendingResolutionPhase : - boundEnv.info.pendingResolutionPhase; - - return bestSym; } /** @@ -2763,8 +2708,8 @@ * the receiver argument type is used to infer an instantiation for the raw * qualifier type. * - * When a multi-step resolution process is exploited, it is an error - * if two candidates are found (ambiguity). + * When a multi-step resolution process is exploited, the process of picking + * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}. * * This routine returns a pair (T,S), where S is the member reference symbol, * and T is the type of the class in which S is defined. This is necessary as @@ -2779,7 +2724,7 @@ List typeargtypes, MethodCheck methodCheck, InferenceContext inferenceContext, - AttrMode mode) { + ReferenceChooser referenceChooser) { site = types.capture(site); ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( @@ -2787,102 +2732,29 @@ //step 1 - bound lookup Env boundEnv = env.dup(env.tree, env.info.dup()); - Symbol origBoundSym; - boolean staticErrorForBound = false; MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext(); boundSearchResolveContext.methodCheck = methodCheck; - Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(), + Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundSearchResolveContext, boundLookupHelper); - SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH; - boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names); - boolean shouldCheckForStaticness = isStaticSelector && - referenceTree.getMode() == ReferenceMode.INVOKE; - if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) { - if (shouldCheckForStaticness) { - if (!boundSym.isStatic()) { - staticErrorForBound = true; - if (hasAnotherApplicableMethod( - boundSearchResolveContext, boundSym, true)) { - boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC; - } else { - boundSearchResultKind = SearchResultKind.BAD_MATCH; - if (!boundSym.kind.isOverloadError()) { - boundSym = methodWithCorrectStaticnessNotFound; - } - } - } else if (!boundSym.kind.isOverloadError()) { - boundSearchResultKind = SearchResultKind.GOOD_MATCH; - } - } - } + ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext); //step 2 - unbound lookup - Symbol origUnboundSym = null; Symbol unboundSym = methodNotFound; - ReferenceLookupHelper unboundLookupHelper = null; Env unboundEnv = env.dup(env.tree, env.info.dup()); - SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH; - boolean staticErrorForUnbound = false; - if (isStaticSelector) { - unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + ReferenceLookupResult unboundRes = referenceNotFound; + if (unboundLookupHelper != null) { MethodResolutionContext unboundSearchResolveContext = new MethodResolutionContext(); unboundSearchResolveContext.methodCheck = methodCheck; - unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(), + unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundSearchResolveContext, unboundLookupHelper); - - if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) { - if (shouldCheckForStaticness) { - if (unboundSym.isStatic()) { - staticErrorForUnbound = true; - if (hasAnotherApplicableMethod( - unboundSearchResolveContext, unboundSym, false)) { - unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC; - } else { - unboundSearchResultKind = SearchResultKind.BAD_MATCH; - if (!unboundSym.kind.isOverloadError()) { - unboundSym = methodWithCorrectStaticnessNotFound; - } - } - } else if (!unboundSym.kind.isOverloadError()) { - unboundSearchResultKind = SearchResultKind.GOOD_MATCH; - } - } - } + unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext); } //merge results Pair res; - Symbol bestSym = choose(boundSym, unboundSym); - if (!bestSym.kind.isOverloadError() && - (staticErrorForBound || staticErrorForUnbound)) { - if (staticErrorForBound) { - boundSym = methodWithCorrectStaticnessNotFound; - } - if (staticErrorForUnbound) { - unboundSym = methodWithCorrectStaticnessNotFound; - } - bestSym = choose(boundSym, unboundSym); - } - if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) { - Symbol symToPrint = origBoundSym; - String errorFragmentToPrint = "non-static.cant.be.ref"; - if (staticErrorForBound && staticErrorForUnbound) { - if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) { - symToPrint = origUnboundSym; - errorFragmentToPrint = "static.method.in.unbound.lookup"; - } - } else { - if (!staticErrorForBound) { - symToPrint = origUnboundSym; - errorFragmentToPrint = "static.method.in.unbound.lookup"; - } - } - log.error(referenceTree.expr.pos(), "invalid.mref", - Kinds.kindName(referenceTree.getMode()), - diags.fragment(errorFragmentToPrint, - Kinds.kindName(symToPrint), symToPrint)); - } + Symbol bestSym = referenceChooser.result(boundRes, unboundRes); res = new Pair<>(bestSym, bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper); env.info.pendingResolutionPhase = bestSym == unboundSym ? @@ -2892,67 +2764,213 @@ return res; } - enum SearchResultKind { - GOOD_MATCH, //type I - BAD_MATCH_MORE_SPECIFIC, //type II - BAD_MATCH, //type III - NOT_APPLICABLE_MATCH //type IV - } - - boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext, - Symbol bestSoFar, boolean staticMth) { - for (Candidate c : resolutionContext.candidates) { - if (resolutionContext.step != c.step || - !c.isApplicable() || - c.sym == bestSoFar) { - continue; - } else { - if (c.sym.isStatic() == staticMth) { - return true; + /** + * This class is used to represent a method reference lookup result. It keeps track of two + * things: (i) the symbol found during a method reference lookup and (ii) the static kind + * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}). + */ + static class ReferenceLookupResult { + + /** + * Static kind associated with a method reference lookup. Erroneous lookups end up with + * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC, + * depending on whether all applicable candidates are static or non-static methods, + * respectively. If a successful lookup has both static and non-static applicable methods, + * its kind is set to BOTH. + */ + enum StaticKind { + STATIC, + NON_STATIC, + BOTH, + UNDEFINED; + + /** + * Retrieve the static kind associated with a given (method) symbol. + */ + static StaticKind from(Symbol s) { + return s.isStatic() ? + STATIC : NON_STATIC; + } + + /** + * Merge two static kinds together. + */ + static StaticKind reduce(StaticKind sk1, StaticKind sk2) { + if (sk1 == UNDEFINED) { + return sk2; + } else if (sk2 == UNDEFINED) { + return sk1; + } else { + return sk1 == sk2 ? sk1 : BOTH; } } } - return false; - } - - //where - private Symbol choose(Symbol boundSym, Symbol unboundSym) { - if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) { - return ambiguityError(boundSym, unboundSym); - } else if (lookupSuccess(boundSym) || - (canIgnore(unboundSym) && !canIgnore(boundSym))) { - return boundSym; - } else if (lookupSuccess(unboundSym) || - (canIgnore(boundSym) && !canIgnore(unboundSym))) { - return unboundSym; - } else { - return boundSym; + + /** The static kind. */ + StaticKind staticKind; + + /** The lookup result. */ + Symbol sym; + + ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) { + this.staticKind = staticKind(sym, resolutionContext); + this.sym = sym; + } + + private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) { + switch (sym.kind) { + case MTH: + case AMBIGUOUS: + return resolutionContext.candidates.stream() + .filter(c -> c.isApplicable() && c.step == resolutionContext.step) + .map(c -> StaticKind.from(c.sym)) + .reduce(StaticKind::reduce) + .orElse(StaticKind.UNDEFINED); + case HIDDEN: + return StaticKind.from(((AccessError)sym).sym); + default: + return StaticKind.UNDEFINED; } } - private boolean lookupSuccess(Symbol s) { - return s.kind == MTH || s.kind == AMBIGUOUS; + /** + * Does this result corresponds to a successful lookup (i.e. one where a method has been found?) + */ + boolean isSuccess() { + return staticKind != StaticKind.UNDEFINED; } - private boolean canIgnore(Symbol s) { - switch (s.kind) { + /** + * Does this result have given static kind? + */ + boolean hasKind(StaticKind sk) { + return this.staticKind == sk; + } + + /** + * Error recovery helper: can this lookup result be ignored (for the purpose of returning + * some 'better' result) ? + */ + boolean canIgnore() { + switch (sym.kind) { case ABSENT_MTH: return true; case WRONG_MTH: InapplicableSymbolError errSym = - (InapplicableSymbolError)s.baseSymbol(); + (InapplicableSymbolError)sym.baseSymbol(); return new Template(MethodCheckDiag.ARITY_MISMATCH.regex()) .matches(errSym.errCandidate().snd); case WRONG_MTHS: InapplicableSymbolsError errSyms = - (InapplicableSymbolsError)s.baseSymbol(); + (InapplicableSymbolsError)sym.baseSymbol(); return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); - case WRONG_STATICNESS: - return false; default: return false; } } + } + + /** + * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup) + * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the + * result of method reference resolution. + */ + abstract class ReferenceChooser { + /** + * Generate a result from a pair of lookup result objects. This method delegates to the + * appropriate result generation routine. + */ + Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { + return unboundRes != referenceNotFound ? + unboundResult(boundRes, unboundRes) : + boundResult(boundRes); + } + + /** + * Generate a symbol from a given bound lookup result. + */ + abstract Symbol boundResult(ReferenceLookupResult boundRes); + + /** + * Generate a symbol from a pair of bound/unbound lookup results. + */ + abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes); + } + + /** + * This chooser implements the selection strategy used during a full lookup; this logic + * is described in JLS SE 8 (15.3.2). + */ + ReferenceChooser basicReferenceChooser = new ReferenceChooser() { + + @Override + Symbol boundResult(ReferenceLookupResult boundRes) { + return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ? + boundRes.sym : //the search produces a non-static method + new BadMethodReferenceError(boundRes.sym, false); + } + + @Override + Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { + if (boundRes.hasKind(StaticKind.STATIC) && + (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) { + //the first search produces a static method and no non-static method is applicable + //during the second search + return boundRes.sym; + } else if (unboundRes.hasKind(StaticKind.NON_STATIC) && + (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) { + //the second search produces a non-static method and no static method is applicable + //during the first search + return unboundRes.sym; + } else if (boundRes.isSuccess() && unboundRes.isSuccess()) { + //both searches produce some result; ambiguity (error recovery) + return ambiguityError(boundRes.sym, unboundRes.sym); + } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { + //Both searches failed to produce a result with correct staticness (i.e. first search + //produces an non-static method). Alternatively, a given search produced a result + //with the right staticness, but the other search has applicable methods with wrong + //staticness (error recovery) + return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true); + } else { + //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) + return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? + unboundRes.sym : boundRes.sym; + } + } + }; + + /** + * This chooser implements the selection strategy used during an arity-based lookup; this logic + * is described in JLS SE 8 (15.12.2.1). + */ + ReferenceChooser structuralReferenceChooser = new ReferenceChooser() { + + @Override + Symbol boundResult(ReferenceLookupResult boundRes) { + return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ? + boundRes.sym : //the search has at least one applicable non-static method + new BadMethodReferenceError(boundRes.sym, false); + } + + @Override + Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) { + if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) { + //the first serach has at least one applicable static method + return boundRes.sym; + } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) { + //the second search has at least one applicable non-static method + return unboundRes.sym; + } else if (boundRes.isSuccess() || unboundRes.isSuccess()) { + //either the first search produces a non-static method, or second search produces + //a non-static method (error recovery) + return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true); + } else { + //both searches fail to produce a result - pick 'better' error using heuristics (error recovery) + return (boundRes.canIgnore() && !unboundRes.canIgnore()) ? + unboundRes.sym : boundRes.sym; + } + } + }; /** * Helper for defining custom method-like lookup logic; a lookup helper @@ -3070,22 +3088,7 @@ * method returns an dummy lookup helper. */ ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { - //dummy loopkup helper that always return 'methodNotFound' - return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { - @Override - ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { - return this; - } - @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { - return methodNotFound; - } - @Override - ReferenceKind referenceKind(Symbol sym) { - Assert.error(); - return null; - } - }; + return null; } /** @@ -3124,12 +3127,31 @@ @Override ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { - if (TreeInfo.isStaticSelector(referenceTree.expr, names) && - argtypes.nonEmpty() && - (argtypes.head.hasTag(NONE) || - types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) { - return new UnboundMethodReferenceLookupHelper(referenceTree, name, - site, argtypes, typeargtypes, maxPhase); + if (TreeInfo.isStaticSelector(referenceTree.expr, names)) { + if (argtypes.nonEmpty() && + (argtypes.head.hasTag(NONE) || + types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) { + return new UnboundMethodReferenceLookupHelper(referenceTree, name, + site, argtypes, typeargtypes, maxPhase); + } else { + return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { + @Override + ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) { + return this; + } + + @Override + Symbol lookup(Env env, MethodResolutionPhase phase) { + return methodNotFound; + } + + @Override + ReferenceKind referenceKind(Symbol sym) { + Assert.error(); + return null; + } + }; + } } else { return super.unboundLookup(inferenceContext); } @@ -3231,16 +3253,10 @@ findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name)); - return sym.kind != MTH || - site.getEnclosingType().hasTag(NONE) || - hasEnclosingInstance(env, site) ? - sym : new InvalidSymbolError(MISSING_ENCL, sym, null) { - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - return diags.create(dkind, log.currentSource(), pos, - "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); - } - }; + return (sym.kind != MTH || + site.getEnclosingType().hasTag(NONE) || + hasEnclosingInstance(env, site)) ? + sym : new BadConstructorReferenceError(sym); } @Override @@ -3613,8 +3629,7 @@ hasLocation = !location.name.equals(names._this) && !location.name.equals(names._super); } - boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) && - name == names.init; + boolean isConstructor = name == names.init; KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind(); Name idname = isConstructor ? site.tsym.name : name; String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); @@ -4019,13 +4034,13 @@ Name sname = s1.name; if (sname == names.init) sname = s1.owner.name; return diags.create(dkind, log.currentSource(), - pos, "ref.ambiguous", sname, - kindName(s1), - s1, - s1.location(site, types), - kindName(s2), - s2, - s2.location(site, types)); + pos, "ref.ambiguous", sname, + kindName(s1), + s1, + s1.location(site, types), + kindName(s2), + s2, + s2.location(site, types)); } /** @@ -4108,6 +4123,52 @@ } /** + * BadMethodReferenceError error class indicating that a method reference symbol has been found, + * but with the wrong staticness. + */ + class BadMethodReferenceError extends StaticError { + + boolean unboundLookup; + + public BadMethodReferenceError(Symbol sym, boolean unboundLookup) { + super(sym); + this.unboundLookup = unboundLookup; + } + + @Override + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { + final String key; + if (!unboundLookup) { + key = "bad.static.method.in.bound.lookup"; + } else if (sym.isStatic()) { + key = "bad.static.method.in.unbound.lookup"; + } else { + key = "bad.instance.method.in.unbound.lookup"; + } + return sym.kind.isOverloadError() ? + ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) : + diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym); + } + } + + /** + * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found, + * but pointing to a class for which an enclosing instance is not available. + */ + class BadConstructorReferenceError extends InvalidSymbolError { + + public BadConstructorReferenceError(Symbol sym) { + super(MISSING_ENCL, sym, "BadConstructorReferenceError"); + } + + @Override + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { + return diags.create(dkind, log.currentSource(), pos, + "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); + } + } + + /** * Helper class for method resolution diagnostic simplification. * Certain resolution diagnostic are rewritten as simpler diagnostic * where the enclosing resolution diagnostic (i.e. 'inapplicable method') diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Tue Jan 20 10:22:44 2015 -0800 @@ -1000,6 +1000,7 @@ l.nonEmpty(); l = l.tail) { ClassSymbol inner = l.head; + inner.markAbstractIfNeeded(types); char flags = (char) adjustFlags(inner.flags_field); if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Jan 20 10:22:44 2015 -0800 @@ -1209,15 +1209,7 @@ if (annos.nonEmpty()) { t = toP(F.at(pos).AnnotatedType(annos, t)); } - // .class is only allowed if there were no annotations - JCExpression nt = bracketsSuffix(t); - if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) { - // t and nt are different if bracketsSuffix parsed a .class. - // The check for nonEmpty covers the case when the whole array is annotated. - // Helper method isAnnotated looks for annos deeply within t. - syntaxError("no.annotations.on.dot.class"); - } - t = nt; + t = bracketsSuffix(t); } else { if ((mode & EXPR) != 0) { mode = EXPR; @@ -1956,6 +1948,12 @@ } t = F.at(pos).Erroneous(List.of(toP(F.at(pos).Select(t, name)))); } else { + Tag tag = t.getTag(); + // Type annotations are illegal on class literals. Annotated non array class literals + // are complained about directly in term3(), Here check for type annotations on dimensions + // taking care to handle some interior dimension(s) being annotated. + if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE) + syntaxError("no.annotations.on.dot.class"); t = toP(F.at(pos).Select(t, names._class)); } } else if ((mode & TYPE) != 0) { diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.DefinedBy.Api; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import javax.lang.model.element.*; @@ -113,13 +114,7 @@ switch (kind) { case ERROR: errorCount++; - boolean prev = log.multipleErrors; - log.multipleErrors = true; - try { - log.error(pos, "proc.messager", msg.toString()); - } finally { - log.multipleErrors = prev; - } + log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString()); break; case WARNING: diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Jan 20 10:22:44 2015 -0800 @@ -262,9 +262,6 @@ compiler.misc.static.mref.with.targs=\ parameterized qualifier on static method reference -compiler.misc.static.bound.mref=\ - static bound method reference - # 0: symbol compiler.err.cant.assign.val.to.final.var=\ cannot assign a value to final variable {0} @@ -2050,12 +2047,16 @@ non-static {0} {1} cannot be referenced from a static context # 0: symbol kind, 1: symbol -compiler.misc.non-static.cant.be.ref=\ - non-static {0} {1} cannot be referenced from a static context +compiler.misc.bad.static.method.in.unbound.lookup=\ + unexpected static {0} {1} found in unbound lookup # 0: symbol kind, 1: symbol -compiler.misc.static.method.in.unbound.lookup=\ - static {0} {1} found in unbound lookup +compiler.misc.bad.instance.method.in.unbound.lookup=\ + unexpected instance {0} {1} found in unbound lookup + +# 0: symbol kind, 1: symbol +compiler.misc.bad.static.method.in.bound.lookup=\ + unexpected static {0} {1} found in bound lookup ## Both arguments ({0}, {1}) are "kindname"s. {0} is a comma-separated list ## of kindnames (the list should be identical to that provided in source. diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ */ public JCDiagnostic error( DiagnosticFlag flag, DiagnosticSource source, DiagnosticPosition pos, Error errorKey) { - JCDiagnostic diag = create(null, defaultErrorFlags, source, pos, errorKey); + JCDiagnostic diag = create(null, EnumSet.copyOf(defaultErrorFlags), source, pos, errorKey); if (flag != null) { diag.setFlag(flag); } @@ -432,7 +432,10 @@ SYNTAX, RECOVERABLE, NON_DEFERRABLE, - COMPRESSED + COMPRESSED, + /** Print multiple errors for same source locations. + */ + MULTIPLE; } private final DiagnosticSource source; diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Tue Jan 20 10:22:44 2015 -0800 @@ -33,6 +33,7 @@ import java.util.AbstractCollection; import java.util.ListIterator; import java.util.NoSuchElementException; +import java.util.stream.Collector; /** A class for generic linked lists. Links are supposed to be * immutable, the only exception being the incremental construction of @@ -537,4 +538,14 @@ return Collections.unmodifiableList(a); } + + /** + * Collect elements into a new list (using a @code{ListBuffer}) + */ + public static Collector, List> collector() { + return Collector.of(ListBuffer::new, + (buf, el)->buf.add(el), + (buf1, buf2)-> { buf1.addAll(buf2); return buf1; }, + buf->buf.toList()); + } } diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ import com.sun.tools.javac.main.Main; import com.sun.tools.javac.main.Option; import com.sun.tools.javac.tree.EndPosTable; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; @@ -191,10 +192,6 @@ */ public boolean dumpOnError; - /** Print multiple errors for same source locations. - */ - public boolean multipleErrors; - /** * Diagnostic listener, if provided through programmatic * interface to javac (JSR 199). @@ -417,7 +414,7 @@ * source name and pos. */ protected boolean shouldReport(JavaFileObject file, int pos) { - if (multipleErrors || file == null) + if (file == null) return true; Pair coords = new Pair<>(file, pos); @@ -580,8 +577,9 @@ break; case ERROR: - if (nerrors < MaxErrors - && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) { + if (nerrors < MaxErrors && + (diagnostic.isFlagSet(DiagnosticFlag.MULTIPLE) || + shouldReport(diagnostic.getSource(), diagnostic.getIntPosition()))) { writeDiagnostic(diagnostic); nerrors++; } diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/AnchorTest.out --- a/langtools/test/tools/doclint/AnchorTest.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/AnchorTest.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,4 +1,4 @@ -AnchorTest.java:19: error: anchor already defined: foo +AnchorTest.java:19: error: anchor already defined: "foo" * ^ AnchorTest.java:24: error: invalid name for anchor: "" @@ -10,28 +10,40 @@ AnchorTest.java:34: error: no value given for anchor * ^ -AnchorTest.java:46: error: anchor already defined: foo +AnchorTest.java:46: error: anchor already defined: "foo" * ^ AnchorTest.java:51: error: invalid name for anchor: "" * ^ +AnchorTest.java:51: error: anchor already defined: "" + * + ^ AnchorTest.java:56: error: invalid name for anchor: "123" * ^ +AnchorTest.java:56: error: anchor already defined: "123" + * + ^ AnchorTest.java:61: error: no value given for anchor * ^ -AnchorTest.java:73: error: anchor already defined: foo +AnchorTest.java:73: error: anchor already defined: "foo" *

text

^ AnchorTest.java:78: error: invalid name for anchor: "" *

text

^ +AnchorTest.java:78: error: anchor already defined: "" + *

text

+ ^ AnchorTest.java:83: error: invalid name for anchor: "123" *

text

^ +AnchorTest.java:83: error: anchor already defined: "123" + *

text

+ ^ AnchorTest.java:88: error: no value given for anchor *

text

^ -12 errors +16 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/AnchorTest2.out --- a/langtools/test/tools/doclint/AnchorTest2.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/AnchorTest2.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,4 +1,4 @@ -AnchorTest2.java:15: error: anchor already defined: AnchorTest2 +AnchorTest2.java:15: error: anchor already defined: "AnchorTest2" /** */ ^ 1 error diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/HtmlTagsTest.out --- a/langtools/test/tools/doclint/HtmlTagsTest.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/HtmlTagsTest.out Tue Jan 20 10:22:44 2015 -0800 @@ -13,6 +13,9 @@ HtmlTagsTest.java:28: error: element not allowed in documentation comments: * ^ +HtmlTagsTest.java:28: error: element not closed: html + * + ^ HtmlTagsTest.java:33: error: block element not allowed within inline element : p *

^ @@ -40,5 +43,5 @@ HtmlTagsTest.java:64: error: tag not allowed here: *

    text
  • ...
^ -13 errors -1 warning +14 errors +1 warning \ No newline at end of file diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/anchorTests/p/Test.javac.out --- a/langtools/test/tools/doclint/anchorTests/p/Test.javac.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,7 +1,7 @@ -Test.java:14:7: compiler.err.proc.messager: anchor already defined: dupTest -Test.java:24:12: compiler.err.proc.messager: anchor already defined: dupTestField -Test.java:27:12: compiler.err.proc.messager: anchor already defined: dupTestMethod -Test.java:32:11: compiler.err.proc.messager: anchor already defined: dupNested -Test.java:40:15: compiler.err.proc.messager: anchor already defined: dupNestedField -Test.java:47:15: compiler.err.proc.messager: anchor already defined: dupNestedMethod +Test.java:14:7: compiler.err.proc.messager: anchor already defined: "dupTest" +Test.java:24:12: compiler.err.proc.messager: anchor already defined: "dupTestField" +Test.java:27:12: compiler.err.proc.messager: anchor already defined: "dupTestMethod" +Test.java:32:11: compiler.err.proc.messager: anchor already defined: "dupNested" +Test.java:40:15: compiler.err.proc.messager: anchor already defined: "dupNestedField" +Test.java:47:15: compiler.err.proc.messager: anchor already defined: "dupNestedMethod" 6 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/anchorTests/p/Test.out --- a/langtools/test/tools/doclint/anchorTests/p/Test.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/anchorTests/p/Test.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,19 +1,19 @@ -Test.java:14: error: anchor already defined: dupTest +Test.java:14: error: anchor already defined: "dupTest" * dupTest again ^ -Test.java:24: error: anchor already defined: dupTestField +Test.java:24: error: anchor already defined: "dupTestField" /** dupTestField again */ ^ -Test.java:27: error: anchor already defined: dupTestMethod +Test.java:27: error: anchor already defined: "dupTestMethod" /** dupTestMethod again */ ^ -Test.java:32: error: anchor already defined: dupNested +Test.java:32: error: anchor already defined: "dupNested" * dupNested again ^ -Test.java:40: error: anchor already defined: dupNestedField +Test.java:40: error: anchor already defined: "dupNestedField" * dupNestedField ^ -Test.java:47: error: anchor already defined: dupNestedMethod +Test.java:47: error: anchor already defined: "dupNestedMethod" * dupNestedMethod ^ 6 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/anchorTests/p/package-info.javac.out --- a/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,2 +1,2 @@ -package-info.java:12:7: compiler.err.proc.messager: anchor already defined: here +package-info.java:12:7: compiler.err.proc.messager: anchor already defined: "here" 1 error diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/anchorTests/p/package-info.out --- a/langtools/test/tools/doclint/anchorTests/p/package-info.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,4 +1,4 @@ -package-info.java:12: error: anchor already defined: here +package-info.java:12: error: anchor already defined: "here" * here again ^ 1 error diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out --- a/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,7 +1,7 @@ -AnchorAlreadyDefined.java:14: error: anchor already defined: here +AnchorAlreadyDefined.java:14: error: anchor already defined: "here" * duplicate ^ -AnchorAlreadyDefined.java:15: error: anchor already defined: here +AnchorAlreadyDefined.java:15: error: anchor already defined: "here" *

duplicate

^ 2 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/6304921/TestLog.java --- a/langtools/test/tools/javac/6304921/TestLog.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/6304921/TestLog.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,10 +26,11 @@ * @bug 6304912 * @summary unit test for Log */ +import java.lang.reflect.Field; import java.io.InputStream; -import java.io.IOException; import java.io.OutputStream; import java.net.URI; +import java.util.Set; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import com.sun.tools.javac.file.JavacFileManager; @@ -41,23 +42,34 @@ import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; +import com.sun.tools.javac.util.JCDiagnostic.Factory; import com.sun.tools.javac.util.Options; public class TestLog { - public static void main(String... args) throws IOException { + public static void main(String... args) throws Exception { test(false); test(true); } - static void test(boolean genEndPos) throws IOException { + static void test(boolean genEndPos) throws Exception { Context context = new Context(); Options options = Options.instance(context); options.put("diags", "%b:%s/%o/%e:%_%t%m|%p%m"); Log log = Log.instance(context); - log.multipleErrors = true; + Factory diagnosticFactory = JCDiagnostic.Factory.instance(context); + Field defaultErrorFlagsField = + JCDiagnostic.Factory.class.getDeclaredField("defaultErrorFlags"); + + defaultErrorFlagsField.setAccessible(true); + + Set defaultErrorFlags = + (Set) defaultErrorFlagsField.get(diagnosticFactory); + + defaultErrorFlags.add(DiagnosticFlag.MULTIPLE); JavacFileManager.preRegister(context); ParserFactory pfac = ParserFactory.instance(context); diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java --- a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java Tue Jan 20 10:22:44 2015 -0800 @@ -147,6 +147,7 @@ public int mAttrs; public int mNumParams; public boolean mSynthetic; + public boolean mIsLambda; public boolean mIsConstructor; public boolean mIsClinit; public boolean mIsBridge; @@ -165,6 +166,7 @@ mIsClinit = mName.equals(""); prefix = cname + "." + mName + "() - "; mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE); + mIsLambda = mSynthetic && mName.startsWith("lambda$"); if (mIsClinit) { sb = new StringBuilder(); // Discard output @@ -225,7 +227,7 @@ // IMPL: Whether MethodParameters attributes will be generated // for some synthetics is unresolved. For now, assume no. - if (mSynthetic) { + if (mSynthetic && !mIsLambda) { warn(prefix + "synthetic has MethodParameter attribute"); } @@ -349,10 +351,12 @@ } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) { expect = "name"; allowMandated = true; - } else if (mIsBridge) { + } else if (mIsBridge || mIsLambda) { allowSynthetic = true; /* you can't expect an special name for bridges' parameters. - * The name of the original parameters are now copied. + * The name of the original parameters are now copied. Likewise + * for a method encoding the lambda expression, names are derived + * from source lambda's parameters and captured enclosing locals. */ expect = null; } diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/MethodParameters/LambdaTest.java --- a/langtools/test/tools/javac/MethodParameters/LambdaTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8006582 + * @bug 8006582 8037546 * @summary javac should generate method parameters correctly. * @build Tester * @compile -parameters LambdaTest.java @@ -31,8 +31,8 @@ */ /** - * Parameter names are not recorded for lambdas. This test verifies - * that there are no MethodParameters attribute for lambdas. + * Post https://bugs.openjdk.java.net/browse/JDK-8037546, this test verifies + * that MethodParameters attribute for lambdas are emitted properly. */ class LambdaTest { diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/MethodParameters/LambdaTest.out --- a/langtools/test/tools/javac/MethodParameters/LambdaTest.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,7 +1,7 @@ class LambdaTest -- LambdaTest.() LambdaTest.foo(i) -LambdaTest.lambda$static$1(arg0)/*synthetic*/ -LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/ +LambdaTest.lambda$static$1(x1/*synthetic*/)/*synthetic*/ +LambdaTest.lambda$null$0(final cap$0/*synthetic*/, x2/*synthetic*/)/*synthetic*/ static interface LambdaTest$I -- inner LambdaTest$I.m(x) diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java --- a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java Tue Jan 20 10:22:44 2015 -0800 @@ -277,7 +277,7 @@ param = "final " + param; } sb.append(sep).append(param); - if (!m.isBridge() && !expect.equals(param)) { + if (!m.isBridge() && !m.getName().startsWith("lambda$") && !expect.equals(param)) { error(prefix + "param[" + i + "]='" + param + "' expected '" + expect + "'"); break; diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java Tue Jan 20 10:22:44 2015 -0800 @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8027262 + * @bug 8027262 8027888 * @summary A class expression cannot be annotated. * @compile/fail/ref=AnnotatedClassExpr.out -XDrawDiagnostics AnnotatedClassExpr.java */ @@ -10,6 +10,12 @@ class AnnotatedClassExpr { static void main() { Object o1 = @A int.class; + o1 = @A int [] . class; + o1 = int @A [] . class; + o1 = int [] @A [] . class; + o1 = AnnotatedClassExpr @A [] .class; + o1 = @A AnnotatedClassExpr @A [] .class; + o1 = @A AnnotatedClassExpr.class; } } diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.out --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,2 +1,8 @@ AnnotatedClassExpr.java:12:29: compiler.err.no.annotations.on.dot.class -1 error +AnnotatedClassExpr.java:13:27: compiler.err.no.annotations.on.dot.class +AnnotatedClassExpr.java:14:27: compiler.err.no.annotations.on.dot.class +AnnotatedClassExpr.java:15:30: compiler.err.no.annotations.on.dot.class +AnnotatedClassExpr.java:16:41: compiler.err.no.annotations.on.dot.class +AnnotatedClassExpr.java:17:44: compiler.err.no.annotations.on.dot.class +AnnotatedClassExpr.java:18:37: compiler.err.no.annotations.on.dot.class +7 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/classfiles/InnerClasses/T8068517.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/classfiles/InnerClasses/T8068517.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** @test + * @bug 8034854 + * @summary Verify that nested enums have correct abstract flag in the InnerClasses attribute. + * @library /tools/lib + * @build ToolBox T8068517 + * @run main T8068517 + */ + +import com.sun.tools.javac.util.Assert; +import java.util.Arrays; +import javax.tools.JavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +public class T8068517 { + + public static void main(String[] args) throws Exception { + new T8068517().run(); + } + + void run() throws Exception { + runTest("class A {\n" + + " enum AInner implements Runnable {\n" + + " A {\n" + + " public void run() {}\n" + + " };\n" + + " }\n" + + "}\n", + "class B {\n" + + " A.AInner a;\n" + + "}"); + runTest("class A {\n" + + " enum AInner implements Runnable {\n" + + " A {\n" + + " public void run() {}\n" + + " };\n" + + " }\n" + + " AInner aInner;\n" + + "}\n", + "class B {\n" + + " void test(A a) {;\n" + + " switch (a.aInner) {\n" + + " case A: break;\n" + + " }\n" + + " };\n" + + "}"); + runTest("class A {\n" + + " enum AInner implements Runnable {\n" + + " A {\n" + + " public void run() {}\n" + + " };\n" + + " }\n" + + " AInner aInner;\n" + + "}\n", + "class B {\n" + + " void test(A a) {;\n" + + " System.err.println(a.aInner.toString());\n" + + " };\n" + + "}"); + runTest("class A {\n" + + " enum AInner implements Runnable {\n" + + " A {\n" + + " public void run() {}\n" + + " };\n" + + " }\n" + + " AInner aInner() {\n" + + " return null;\n" + + " }\n" + + "}\n", + "class B {\n" + + " void test(A a) {;\n" + + " System.err.println(a.aInner().toString());\n" + + " };\n" + + "}"); + } + + void runTest(String aJava, String bJava) throws Exception { + try (JavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) { + ToolBox tb = new ToolBox(); + ToolBox.MemoryFileManager memoryFM1 = new ToolBox.MemoryFileManager(fm); + tb.new JavacTask().fileManager(memoryFM1) + .sources(aJava, bJava) + .run(); + ToolBox.MemoryFileManager memoryFM2 = new ToolBox.MemoryFileManager(fm); + tb.new JavacTask().fileManager(memoryFM2) + .sources(bJava, aJava) + .run(); + + Assert.check(Arrays.equals(memoryFM1.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"), + memoryFM2.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"))); + } + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/BadInstanceMethodInUnboundLookup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/BadInstanceMethodInUnboundLookup.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.bad.instance.method.in.unbound.lookup +// key: compiler.misc.invalid.mref +// key: compiler.err.prob.found.req + +class BadInstanceMethodInUnboundLookup { + + interface SAM { + void m(Integer u); + } + + void f(Integer i) { } + + static void test() { + SAM s = BadInstanceMethodInUnboundLookup::f; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/BadStaticMethodInBoundLookup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInBoundLookup.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.invalid.mref +// key: compiler.misc.bad.static.method.in.bound.lookup +// key: compiler.err.prob.found.req + +class BadStaticMethodInBoundLookup { + + Runnable r = new BadStaticMethodInBoundLookup()::m; + + static void m() { } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/BadStaticMethodInUnboundLookup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInUnboundLookup.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.invalid.mref +// key: compiler.misc.bad.static.method.in.unbound.lookup +// key: compiler.err.prob.found.req + +class BadStaticMethodInUnboundLookup { + + interface SAM { + void m(BadStaticMethodInUnboundLookup m); + } + + SAM s = BadStaticMethodInUnboundLookup::m; + + static void m() { } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java --- a/langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// key: compiler.misc.non-static.cant.be.ref -// key: compiler.err.invalid.mref - -class NonStaticCantBeRefFragment { - - interface SAM { - void m(Integer u); - } - - void f(Integer i) { } - - static void test() { - SAM s = NonStaticCantBeRefFragment::f; - } -} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/StaticBoundMref.java --- a/langtools/test/tools/javac/diags/examples/StaticBoundMref.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// key: compiler.err.invalid.mref -// key: compiler.misc.static.bound.mref - -class StaticBoundMref { - - Runnable r = new StaticBoundMref()::m; - - static void m() { } -} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/diags/examples/StaticMethodInUnboundLookup.java --- a/langtools/test/tools/javac/diags/examples/StaticMethodInUnboundLookup.java Thu Jan 15 19:23:49 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// key: compiler.err.invalid.mref -// key: compiler.misc.static.method.in.unbound.lookup - -class StaticBoundMref { - - interface SAM { - void m(StaticBoundMref m); - } - - SAM s = StaticBoundMref::m; - - static void m() { } -} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/generics/LowerBoundBottomTypeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/LowerBoundBottomTypeTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8062358 + * @summary ClassCastException in TransTypes.visitApply + * @compile LowerBoundBottomTypeTest.java +*/ + +public class LowerBoundBottomTypeTest { + void g() { + f().getInIntf3().getInIntf2().getInIntf1().getA(); + } + interface IntfA { + int getA(); + } + + interface Intf1 { + A getInIntf1(); + } + + interface Intf2 { + Intf1 getInIntf2(); + } + + interface Intf3 { + Intf2 getInIntf3(); + } + + Intf3 f() { + return null; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference22.out --- a/langtools/test/tools/javac/lambda/MethodReference22.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference22.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,9 +1,9 @@ -MethodReference22.java:40:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) -MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) -MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) -MethodReference22.java:55:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String)) -MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) +MethodReference22.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String))) +MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String))) +MethodReference22.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String))) +MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String))) +MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)) +MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m3(MethodReference22,java.lang.String))) MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)) MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference28.out --- a/langtools/test/tools/javac/lambda/MethodReference28.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference28.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,7 +1,7 @@ MethodReference28.java:31:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch))) MethodReference28.java:32:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference28.java:33:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String)))) -MethodReference28.java:37:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.Integer)) +MethodReference28.java:37:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.Integer))) MethodReference28.java:38:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch))) MethodReference28.java:39:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference28.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String)))) diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference51.out --- a/langtools/test/tools/javac/lambda/MethodReference51.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference51.out Tue Jan 20 10:22:44 2015 -0800 @@ -2,6 +2,6 @@ MethodReference51.java:40:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, f, java.lang.String, int, kindname.class, MethodReference51, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference51.java:41:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, g, int,{(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Integer,java.lang.Number), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Number,java.lang.Integer), (compiler.misc.arg.length.mismatch))})) MethodReference51.java:42:32: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: g, kindname.method, g(java.lang.Integer,java.lang.Number), MethodReference51, kindname.method, g(java.lang.Number,java.lang.Integer), MethodReference51)) -MethodReference51.java:43:21: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, h(int)) +MethodReference51.java:43:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, h(int))) MethodReference51.java:44:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.not.def.access.class.intf.cant.access: j(int), MethodReference51.Foo)) 6 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference55.out --- a/langtools/test/tools/javac/lambda/MethodReference55.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference55.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,3 +1,3 @@ -MethodReference55.java:36:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref) -MethodReference55.java:39:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref) +MethodReference55.java:36:11: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object))) +MethodReference55.java:39:9: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference55.V, @1384, kindname.class, MethodReference55, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object)))) 2 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference68.out --- a/langtools/test/tools/javac/lambda/MethodReference68.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference68.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,3 +1,2 @@ MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object) -MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName()) -2 errors +1 error diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/MethodReference73.out --- a/langtools/test/tools/javac/lambda/MethodReference73.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/MethodReference73.out Tue Jan 20 10:22:44 2015 -0800 @@ -2,12 +2,12 @@ MethodReference73.java:90:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference73,java.lang.String), MethodReference73, kindname.method, m2(java.lang.String), MethodReference73)) MethodReference73.java:91:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference73,java.lang.String), MethodReference73, kindname.method, m3(java.lang.String), MethodReference73)) MethodReference73.java:92:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference73,java.lang.String), MethodReference73, kindname.method, m4(java.lang.String), MethodReference73)) -MethodReference73.java:100:18: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m9(MethodReference73,java.lang.String)) -MethodReference73.java:101:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m10(MethodReference73,java.lang.String)) -MethodReference73.java:102:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m11(java.lang.String)) -MethodReference73.java:103:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String)) -MethodReference73.java:104:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m13(MethodReference73,java.lang.String)) -MethodReference73.java:105:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String)) -MethodReference73.java:106:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m15(MethodReference73,java.lang.String)) +MethodReference73.java:100:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m9, kindname.method, m9(MethodReference73,java.lang.String), MethodReference73, kindname.method, m9(java.lang.String), MethodReference73)) +MethodReference73.java:101:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m10(MethodReference73,java.lang.String))) +MethodReference73.java:102:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m11, kindname.method, m11(MethodReference73,java.lang.String), MethodReference73, kindname.method, m11(java.lang.String), MethodReference73)) +MethodReference73.java:103:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String))) +MethodReference73.java:104:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m13(MethodReference73,java.lang.String))) +MethodReference73.java:105:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String))) +MethodReference73.java:106:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m15, kindname.method, m15(MethodReference73,java.lang.String), MethodReference73, kindname.method, m15(java.lang.String), MethodReference73)) MethodReference73.java:108:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m16, MethodReference73,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(MethodReference73,java.lang.String,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(java.lang.String,int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference73, java.lang.String)))})) 12 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/TargetType60.out --- a/langtools/test/tools/javac/lambda/TargetType60.out Thu Jan 15 19:23:49 2015 -0800 +++ b/langtools/test/tools/javac/lambda/TargetType60.out Tue Jan 20 10:22:44 2015 -0800 @@ -1,6 +1,6 @@ TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, g(TargetType60.Sam1), TargetType60 TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam1), TargetType60, kindname.method, g(TargetType60.Sam2), TargetType60 -TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam1), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam2), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, n2, , U,java.lang.String, (compiler.misc.location: kindname.class, TargetType60, null)))))} +TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam1), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam2), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, n2(TargetType60,java.lang.String)))))} TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 5 errors diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferencePackagePrivateQualifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferencePackagePrivateQualifier.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8068254 + * @summary Method reference uses wrong qualifying type + * @author srikanth + * @run main MethodReferencePackagePrivateQualifier + */ +import pkg.B; +public class MethodReferencePackagePrivateQualifier { + public static void main(String... args) { + pkg.B.m(); + Runnable r = pkg.B::m; + r.run(); + r = B::m; + r.run(); + if (!pkg.B.result.equals("A.m()A.m()A.m()")) + throw new AssertionError("Incorrect result"); + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/lambda/methodReferenceExecution/pkg/B.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/pkg/B.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package pkg; +class A { + public static void m() { + B.result += "A.m()"; + } +} + +public class B extends A { + public static String result = ""; +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/processing/TestMultipleErrors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/TestMultipleErrors.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * @test + * @bug 8066843 + * @summary Annotation processors should be able to print multiple errors at the same location. + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor TestMultipleErrors + * @compile/fail/ref=TestMultipleErrors.out -XDrawDiagnostics -processor TestMultipleErrors TestMultipleErrors.java + */ + +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.tools.Diagnostic.Kind; +import com.sun.source.util.TreePath; +import com.sun.source.util.Trees; + +public class TestMultipleErrors extends JavacTestingAbstractProcessor { + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (Element root : roundEnv.getRootElements()) { + processingEnv.getMessager().printMessage(Kind.ERROR, "error1", root); + processingEnv.getMessager().printMessage(Kind.ERROR, "error2", root); + + Trees trees = Trees.instance(processingEnv); + TreePath path = trees.getPath(root); + + trees.printMessage(Kind.ERROR, "error3", path.getLeaf(), path.getCompilationUnit()); + trees.printMessage(Kind.ERROR, "error4", path.getLeaf(), path.getCompilationUnit()); + } + return true; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 langtools/test/tools/javac/processing/TestMultipleErrors.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/processing/TestMultipleErrors.out Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,5 @@ +TestMultipleErrors.java:41:8: compiler.err.proc.messager: error1 +TestMultipleErrors.java:41:8: compiler.err.proc.messager: error2 +TestMultipleErrors.java:41:8: compiler.err.proc.messager: error3 +TestMultipleErrors.java:41:8: compiler.err.proc.messager: error4 +4 errors diff -r 6b55dd30a0ba -r 0388b3b63648 make/Images.gmk --- a/make/Images.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/Images.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -29,7 +29,7 @@ include MakeBase.gmk TOOL_TARGETS := -JDK_TARGETS := +JDK_TARGETS := JRE_TARGETS := # Hook to include the corresponding custom file, if present. @@ -69,7 +69,7 @@ jdk.naming.rmi jdk.sctp jdk.security.auth # Replacing double-comma with a single comma is to workaround the issue -# with some version of make on windows that doesn't substitute spaces +# with some version of make on windows that doesn't substitute spaces # with one comma properly as with make 4.0 define SubstComma $(subst $(COMMA)$(COMMA),$(COMMA),$(subst $(SPACE),$(COMMA),$(strip $1))) diff -r 6b55dd30a0ba -r 0388b3b63648 make/MakeHelpers.gmk --- a/make/MakeHelpers.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/MakeHelpers.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -353,7 +353,7 @@ # Helper macro for DeclareRecipesForPhase # Declare a recipe for calling the module and phase specific makefile. # If there are multiple makefiles to call, create a rule for each topdir -# that contains a makefile with the target $module-$suffix-$repodir, +# that contains a makefile with the target $module-$suffix-$repodir, # (i.e: java.base-gensrc-jdk) # Normally there is only one makefile, and the target will just be # $module-$suffix diff -r 6b55dd30a0ba -r 0388b3b63648 make/ModuleWrapper.gmk --- a/make/ModuleWrapper.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/ModuleWrapper.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -26,7 +26,7 @@ ################################################################################ # This makefile is called from Main.gmk, through a macro in MakeHelpers.gmk # and wraps calls to makefiles for specific modules and build phases. Having -# this wrapper reduces the need for boilerplate code. It also provides +# this wrapper reduces the need for boilerplate code. It also provides # opportunity for automatic copying of files to an interim exploded runnable # image. diff -r 6b55dd30a0ba -r 0388b3b63648 make/common/JavaCompilation.gmk --- a/make/common/JavaCompilation.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/common/JavaCompilation.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -538,7 +538,7 @@ $1_REMOTE:=--server:portfile=$$($1_SJAVAC_PORTFILE),id=$1,sjavac=$$(subst $$(SPACE),%20,$$(subst $$(COMMA),%2C,$$(strip $$($1_SERVER_JVM) $$($1_SJAVAC)))) $$($1_BIN)/_the.$1_batch: $$($1_SRCS) $$($1_DEPENDS) - $(MKDIR) -p $$(@D) + $(MKDIR) -p $$(@D) $$(dir $$($1_SJAVAC_PORTFILE)) # As a workaround for sjavac not tracking api changed from the classpath, force full # recompile if an external dependency, which is something other than a source # change, triggered this compilation. diff -r 6b55dd30a0ba -r 0388b3b63648 make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/common/NativeCompilation.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -439,8 +439,10 @@ # Now call add_native_source for each source file we are going to compile. $$(foreach p,$$($1_SRCS), \ $$(eval $$(call add_native_source,$1,$$p,$$($1_OBJECT_DIR), \ - $(SYSROOT_CFLAGS) $$($1_CFLAGS) $$($1_EXTRA_CFLAGS),$$($1_CC), \ - $(SYSROOT_CFLAGS) $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS),$$($1_CXX),$$($1_OBJC),$$($1_ASFLAGS)))) + $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $(SYSROOT_CFLAGS), \ + $$($1_CC), \ + $$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) $(SYSROOT_CFLAGS), \ + $$($1_CXX),$$($1_OBJC),$$($1_ASFLAGS)))) # On windows we need to create a resource file ifeq ($(OPENJDK_TARGET_OS), windows) @@ -575,10 +577,11 @@ $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_REAL_MAPFILE) \ $$($1_DEBUGINFO_EXTRA_DEPS) - $$(call LINKING_MSG,$$($1_BASENAME)) - $$($1_LD) $(SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(LD_OUT_OPTION)$$@ \ - $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) \ - $$($1_EXTRA_LDFLAGS_SUFFIX) + $(ECHO) $(LOG_INFO) "Linking $$($1_BASENAME)" + $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ + $(LD_OUT_OPTION)$$@ \ + $$($1_EXPECTED_OBJS) $$($1_RES) \ + $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) $$($1_CREATE_DEBUGINFO_CMDS) # Touch target to make sure it has a later time stamp than the debug # symbol files to avoid unnecessary relinking on rebuild. @@ -602,10 +605,11 @@ $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_GEN_MANIFEST) \ $$($1_DEBUGINFO_EXTRA_DEPS) - $$(call LINKING_EXE_MSG,$$($1_BASENAME)) - $$($1_LDEXE) $(SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(EXE_OUT_OPTION)$$($1_TARGET) \ - $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_LDFLAGS_SUFFIX) \ - $$($1_EXTRA_LDFLAGS_SUFFIX) + $(ECHO) $(LOG_INFO) "Linking executable $$($1_BASENAME)" + $$($1_LDEXE) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $(SYSROOT_LDFLAGS) \ + $(EXE_OUT_OPTION)$$($1_TARGET) \ + $$($1_EXPECTED_OBJS) $$($1_RES) \ + $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX) ifneq (,$$($1_GEN_MANIFEST)) $(MT) -nologo -manifest $$($1_GEN_MANIFEST) -outputresource:$$@;#1 endif diff -r 6b55dd30a0ba -r 0388b3b63648 make/common/SetupJavaCompilers.gmk --- a/make/common/SetupJavaCompilers.gmk Thu Jan 15 19:23:49 2015 -0800 +++ b/make/common/SetupJavaCompilers.gmk Tue Jan 20 10:22:44 2015 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,9 @@ DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally -# To build with all warnings enabled, do the following: +# If warnings needs to be non-fatal for testing purposes use a command like: # make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" -JAVAC_WARNINGS := -Xlint:all,-deprecation -Werror +JAVAC_WARNINGS := -Xlint:all -Werror # The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools # and the interim javac, to be run by the boot jdk. diff -r 6b55dd30a0ba -r 0388b3b63648 make/jprt.properties --- a/make/jprt.properties Thu Jan 15 19:23:49 2015 -0800 +++ b/make/jprt.properties Tue Jan 20 10:22:44 2015 -0800 @@ -269,11 +269,6 @@ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_CMS, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_G1, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_SerialGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_ParallelGC, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_sparcv9_5.11-{product|fastdebug}-c2-GCOld_ParOldGC, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_default_nontiered, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_SerialGC, \ solaris_sparcv9_5.11-{product|fastdebug}-c2-jbb_ParallelGC, \ @@ -293,17 +288,9 @@ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_CMS, \ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_G1, \ solaris_x64_5.11-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_SerialGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParallelGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParOldGC, \ solaris_x64_5.11-{product|fastdebug}-c2-jbb_default_nontiered, \ solaris_x64_5.11-{product|fastdebug}-c2-jbb_SerialGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-jbb_ParallelGC, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_CMS, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_G1, \ - solaris_x64_5.11-{product|fastdebug}-c2-GCOld_ParOldGC + solaris_x64_5.11-{product|fastdebug}-c2-jbb_ParallelGC, my.test.targets.hotspot.linux.i586= \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-jvm98, \ @@ -319,11 +306,6 @@ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ linux_i586_2.6-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_SerialGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_ParallelGC, \ - linux_i586_2.6-product-{c1|c2}-GCOld_CMS, \ - linux_i586_2.6-product-{c1|c2}-GCOld_G1, \ - linux_i586_2.6-product-{c1|c2}-GCOld_ParOldGC, \ linux_i586_2.6-{product|fastdebug}-c1-jbb_SerialGC, \ linux_i586_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \ linux_i586_2.6-{product|fastdebug}-c1-jbb_ParallelGC, \ @@ -340,11 +322,6 @@ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_CMS, \ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_G1, \ linux_x64_2.6-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_SerialGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParallelGC, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_CMS, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_G1, \ - linux_x64_2.6-{product|fastdebug}-c2-GCOld_ParOldGC, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_default_nontiered, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_ParallelGC, \ linux_x64_2.6-{product|fastdebug}-c2-jbb_G1, \ @@ -359,11 +336,6 @@ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_CMS, \ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_G1, \ macosx_x64_10.7-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_SerialGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParallelGC, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_CMS, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_G1, \ - macosx_x64_10.7-{product|fastdebug}-c2-GCOld_ParOldGC, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_default_nontiered, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_ParallelGC, \ macosx_x64_10.7-{product|fastdebug}-c2-jbb_G1, \ @@ -382,11 +354,6 @@ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_G1, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-GCBasher_ParOldGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_SerialGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_ParallelGC, \ - windows_i586_6.1-product-{c1|c2}-GCOld_CMS, \ - windows_i586_6.1-product-{c1|c2}-GCOld_G1, \ - windows_i586_6.1-product-{c1|c2}-GCOld_ParOldGC, \ windows_i586_6.1-{product|fastdebug}-{c1|c2}-jbb_default, \ windows_i586_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \ windows_i586_6.1-product-{c1|c2}-jbb_ParallelGC, \ @@ -406,11 +373,6 @@ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_CMS, \ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_G1, \ windows_x64_6.1-{product|fastdebug}-c2-GCBasher_ParOldGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_SerialGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParallelGC, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_CMS, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_G1, \ - windows_x64_6.1-{product|fastdebug}-c2-GCOld_ParOldGC, \ windows_x64_6.1-{product|fastdebug}-c2-jbb_default, \ windows_x64_6.1-{product|fastdebug}-c2-jbb_default_nontiered, \ windows_x64_6.1-product-c2-jbb_CMS, \ @@ -486,6 +448,8 @@ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler_3}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_compiler_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc}, \ + ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc_closed}, \ + ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_gc_gcold}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_runtime_closed}, \ ${my.make.rule.test.targets.hotspot.reg.group:GROUP=hotspot_serviceability}, \ diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/.hgtags --- a/nashorn/.hgtags Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/.hgtags Tue Jan 20 10:22:44 2015 -0800 @@ -279,3 +279,4 @@ 8ae8dff2a28f3b8831cce97ae0c7a957c5dc650a jdk9-b43 50ee576062726e536d1bb9a5eadd8fd4470128fc jdk9-b44 3c2bbeda038aef7061455fec604db7d8a342fac5 jdk9-b45 +2ecf0a617f0f9af1ffd278a0c70e76f1946ce773 jdk9-b46 diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Tue Jan 20 10:22:44 2015 -0800 @@ -491,8 +491,9 @@ // We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be // valid for us to convert return values proactively. Also, since we don't know what setters will be - // invoked, we'll conservatively presume Object return type. - final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class); + // invoked, we'll conservatively presume Object return type. The one exception is void return. + final MethodType origType = callSiteDescriptor.getMethodType(); + final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class); // What's below is basically: // foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation), @@ -508,7 +509,7 @@ // Bind property setter handle to the expected setter type and linker services. Type is // MethodHandle(Object, String, Object) final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, - CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices); + callSiteDescriptor.changeMethodType(setterType), linkerServices); // Cast getter to MethodHandle(O, N, V) final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType( diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Tue Jan 20 10:22:44 2015 -0800 @@ -123,7 +123,6 @@ varArgMethods = new ArrayList<>(methodHandles.size()); final int argNum = callSiteType.parameterCount(); for(MethodHandle mh: methodHandles) { - mh = mh.asType(mh.type().changeReturnType(commonRetType)); if(mh.isVarargsCollector()) { final MethodHandle asFixed = mh.asFixedArity(); if(argNum == asFixed.type().parameterCount()) { diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java Tue Jan 20 10:22:44 2015 -0800 @@ -118,17 +118,13 @@ public static Class getCommonLosslessConversionType(final Class c1, final Class c2) { if(c1 == c2) { return c1; + } else if (c1 == void.class || c2 == void.class) { + return Object.class; } else if(isConvertibleWithoutLoss(c2, c1)) { return c1; } else if(isConvertibleWithoutLoss(c1, c2)) { return c2; - } - if(c1 == void.class) { - return c2; - } else if(c2 == void.class) { - return c1; - } - if(c1.isPrimitive() && c2.isPrimitive()) { + } else if(c1.isPrimitive() && c2.isPrimitive()) { if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) { // byte + char = int return int.class; @@ -268,20 +264,24 @@ } /** - * Determines whether a type can be converted to another without losing any - * precision. + * Determines whether a type can be converted to another without losing any precision. As a special case, + * void is considered convertible only to Object and void, while anything can be converted to void. This + * is because a target type of void means we don't care about the value, so the conversion is always + * permissible. * * @param sourceType the source type * @param targetType the target type * @return true if lossless conversion is possible */ public static boolean isConvertibleWithoutLoss(final Class sourceType, final Class targetType) { - if(targetType.isAssignableFrom(sourceType)) { + if(targetType.isAssignableFrom(sourceType) || targetType == void.class) { return true; } if(sourceType.isPrimitive()) { if(sourceType == void.class) { - return false; // Void can't be losslessly represented by any type + // Void should be losslessly representable by Object, either as null or as a custom value that + // can be set with DynamicLinkerFactory.setAutoConversionStrategy. + return targetType == Object.class; } if(targetType.isPrimitive()) { return isProperPrimitiveLosslessSubtype(sourceType, targetType); diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Tue Jan 20 10:22:44 2015 -0800 @@ -703,7 +703,7 @@ final ScriptFunction func = getProgramFunction(clazz, scope); Object evalThis; if (directEval) { - evalThis = callThis instanceof ScriptObject || strictFlag ? callThis : global; + evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global; } else { evalThis = global; } diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Tue Jan 20 10:22:44 2015 -0800 @@ -68,6 +68,8 @@ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); + private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED); + /** * The default dynalink relink threshold for megamorphisism is 8. In the case * of object fields only, it is fine. However, with dual fields, in order to get @@ -189,7 +191,7 @@ * @return true if the obj is an instance of @FunctionalInterface interface */ public static boolean isFunctionalInterfaceObject(final Object obj) { - return !JSType.isPrimitive(obj) && (NashornBottomLinker.getFunctionalInterfaceMethod(obj.getClass()) != null); + return !JSType.isPrimitive(obj) && (NashornBeansLinker.getFunctionalInterfaceMethod(obj.getClass()) != null); } /** @@ -481,14 +483,16 @@ private static MethodHandle unboxReturnType(final MethodHandle target, final MethodType newType) { final MethodType targetType = target.type(); final Class oldReturnType = targetType.returnType(); + final Class newReturnType = newType.returnType(); if (TypeUtilities.isWrapperType(oldReturnType)) { - final Class newReturnType = newType.returnType(); if (newReturnType.isPrimitive()) { // The contract of setAutoConversionStrategy is such that the difference between newType and targetType // can only be JLS method invocation conversions. assert TypeUtilities.isMethodInvocationConvertible(oldReturnType, newReturnType); return MethodHandles.explicitCastArguments(target, targetType.changeReturnType(newReturnType)); } + } else if (oldReturnType == void.class && newReturnType == Object.class) { + return MethodHandles.filterReturnValue(target, VOID_TO_OBJECT); } return target; } diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Tue Jan 20 10:22:44 2015 -0800 @@ -25,20 +25,29 @@ package jdk.nashorn.internal.runtime.linker; +import static jdk.nashorn.internal.lookup.Lookup.MH; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; + import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.linker.ConversionComparator.Comparison; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardingDynamicLinker; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; +import jdk.internal.dynalink.support.Guards; import jdk.internal.dynalink.support.Lookup; import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.ConsString; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.options.Options; /** @@ -68,19 +77,49 @@ FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class); } + // cache of @FunctionalInterface method of implementor classes + private static final ClassValue FUNCTIONAL_IFACE_METHOD = new ClassValue() { + @Override + protected Method computeValue(final Class type) { + return findFunctionalInterfaceMethod(type); + } + }; + private final BeansLinker beansLinker = new BeansLinker(); @Override public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { - if (linkRequest.getReceiver() instanceof ConsString) { + final Object self = linkRequest.getReceiver(); + final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor(); + if (self instanceof ConsString) { // In order to treat ConsString like a java.lang.String we need a link request with a string receiver. final Object[] arguments = linkRequest.getArguments(); arguments[0] = ""; - final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(linkRequest.getCallSiteDescriptor(), arguments); + final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(desc, arguments); final GuardedInvocation invocation = getGuardedInvocation(beansLinker, forgedLinkRequest, linkerServices); // If an invocation is found we add a filter that makes it work for both Strings and ConsStrings. return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING); } + + if (self != null && "call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { + // Support dyn:call on any object that supports some @FunctionalInterface + // annotated interface. This way Java method, constructor references or + // implementations of java.util.function.* interfaces can be called as though + // those are script functions. + final Method m = getFunctionalInterfaceMethod(self.getClass()); + if (m != null) { + final MethodType callType = desc.getMethodType(); + // 'callee' and 'thiz' passed from script + actual arguments + if (callType.parameterCount() != m.getParameterCount() + 2) { + throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self)); + } + return new GuardedInvocation( + // drop 'thiz' passed from the script. + MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)), + Guards.getInstanceOfGuard(m.getDeclaringClass())).asTypeSafeReturn( + new NashornBeansLinkerServices(linkerServices), callType); + } + } return getGuardedInvocation(beansLinker, linkRequest, linkerServices); } @@ -137,6 +176,38 @@ return arg instanceof ConsString ? arg.toString() : arg; } + private static Method findFunctionalInterfaceMethod(final Class clazz) { + if (clazz == null) { + return null; + } + + for (final Class iface : clazz.getInterfaces()) { + // check accessiblity up-front + if (! Context.isAccessibleClass(iface)) { + continue; + } + + // check for @FunctionalInterface + if (iface.isAnnotationPresent(FunctionalInterface.class)) { + // return the first abstract method + for (final Method m : iface.getMethods()) { + if (Modifier.isAbstract(m.getModifiers())) { + return m; + } + } + } + } + + // did not find here, try super class + return findFunctionalInterfaceMethod(clazz.getSuperclass()); + } + + // Returns @FunctionalInterface annotated interface's single abstract + // method. If not found, returns null. + static Method getFunctionalInterfaceMethod(final Class clazz) { + return FUNCTIONAL_IFACE_METHOD.get(clazz); + } + private static class NashornBeansLinkerServices implements LinkerServices { private final LinkerServices linkerServices; diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Tue Jan 20 10:22:44 2015 -0800 @@ -30,9 +30,6 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import jdk.internal.dynalink.CallSiteDescriptor; @@ -45,7 +42,6 @@ import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.Guards; import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; @@ -95,22 +91,6 @@ } throw typeError("not.a.function", ScriptRuntime.safeToString(self)); case "call": - // Support dyn:call on any object that supports some @FunctionalInterface - // annotated interface. This way Java method, constructor references or - // implementations of java.util.function.* interfaces can be called as though - // those are script functions. - final Method m = getFunctionalInterfaceMethod(self.getClass()); - if (m != null) { - final MethodType callType = desc.getMethodType(); - // 'callee' and 'thiz' passed from script + actual arguments - if (callType.parameterCount() != m.getParameterCount() + 2) { - throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self)); - } - return Bootstrap.asTypeSafeReturn(new GuardedInvocation( - // drop 'thiz' passed from the script. - MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)), - Guards.getInstanceOfGuard(m.getDeclaringClass())), linkerServices, desc); - } if(BeansLinker.isDynamicConstructor(self)) { throw typeError("constructor.requires.new", ScriptRuntime.safeToString(self)); } @@ -218,44 +198,4 @@ } return ScriptRuntime.safeToString(linkRequest.getArguments()[1]); } - - // cache of @FunctionalInterface method of implementor classes - private static final ClassValue FUNCTIONAL_IFACE_METHOD = new ClassValue() { - @Override - protected Method computeValue(final Class type) { - return findFunctionalInterfaceMethod(type); - } - - private Method findFunctionalInterfaceMethod(final Class clazz) { - if (clazz == null) { - return null; - } - - for (final Class iface : clazz.getInterfaces()) { - // check accessiblity up-front - if (! Context.isAccessibleClass(iface)) { - continue; - } - - // check for @FunctionalInterface - if (iface.isAnnotationPresent(FunctionalInterface.class)) { - // return the first abstract method - for (final Method m : iface.getMethods()) { - if (Modifier.isAbstract(m.getModifiers())) { - return m; - } - } - } - } - - // did not find here, try super class - return findFunctionalInterfaceMethod(clazz.getSuperclass()); - } - }; - - // Returns @FunctionalInterface annotated interface's single abstract - // method. If not found, returns null. - static Method getFunctionalInterfaceMethod(final Class clazz) { - return FUNCTIONAL_IFACE_METHOD.get(clazz); - } } diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/script/basic/JDK-8020324.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Tue Jan 20 10:22:44 2015 -0800 @@ -17,7 +17,7 @@ bean.readWrite = 18: 18 obj1.readWrite: 18 obj1.getReadWrite(): 18 -obj1.setReadWrite(19): null +obj1.setReadWrite(19): undefined obj1.readWrite: 19 bean.readWrite: 19 @@ -52,7 +52,7 @@ PropertyBind.staticReadWrite = 26: 26 obj2.staticReadWrite: 26 obj2.getStaticReadWrite(): 26 -obj2.setStaticReadWrite(27): null +obj2.setStaticReadWrite(27): undefined obj2.staticReadWrite: 27 PropertyBind.staticReadWrite: 27 diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/script/basic/JDK-8068573.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8068573.js Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8068573: POJO setter using [] syntax throws an exception + * + * @test + * @run + */ + +// Invoke a setter using []. It's important that the setter returns void. +var pb = new (Java.type("jdk.nashorn.test.models.PropertyBind")) +var n = "writeOnly"; +pb[n] = 2; +Assert.assertEquals(pb.peekWriteOnly(), 2); + +// Invoke an overloaded setter using []. It's important that one of the +// overloads returns void. +var os = new (Java.type("jdk.nashorn.test.models.OverloadedSetter")) +var n2 = "color"; +os[n2] = 3; // exercise int overload +Assert.assertEquals(os.peekColor(), "3"); +os[n2] = "blue"; // exercise string overload +Assert.assertEquals(os.peekColor(), "blue"); +for each(var x in [42, "42"]) { + os[n2] = x; // exercise both overloads in the same call site + Assert.assertEquals(os.peekColor(), "42"); +} + +// Invoke an overloaded method using [], repeatedly in the same call +// site. It's important that one of the overloads returns void. +var n3="foo"; +var param=["xyz", 1, "zyx", 2]; +var expected=["boo", void 0, "boo", void 0]; +for(var i in param) { + Assert.assertEquals(os[n3](param[i]), expected[i]); +} diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/script/basic/JDK-8068985.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8068985.js Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8068985: Wrong 'this' bound to eval call within a function when caller's 'this' is a Java object + * + * @test + * @run + */ + +function func(arg) { + (function() { print(eval('this')); }).call(arg); +} + +// primitives +func(undefined); +func(null); +func(34.23); +func("hello"); +func(false); + +// script objects +func(this); +func({}); +func({ toString: function() { return "foo" } }); + +// java objects +func(new java.util.Vector()); +var m = new java.util.HashMap(); +m.put("foo", "bar"); +func(m); diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/script/basic/JDK-8068985.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8068985.js.EXPECTED Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,10 @@ +[object global] +[object global] +34.23 +hello +false +[object global] +[object Object] +foo +[] +{foo=bar} diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/script/basic/JDK-8069002.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8069002.js Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8069002: NPE on invoking null (8068889 regression) + * + * @test + * @run + */ + +try { + null(); +} catch (e) { + Assert.assertTrue(e instanceof TypeError); +} diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Jan 15 19:23:49 2015 -0800 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Tue Jan 20 10:22:44 2015 -0800 @@ -30,12 +30,16 @@ import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; + import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Function; import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.Invocable; @@ -680,6 +684,41 @@ assertNull(value); } + // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. + @Test + public void functionalInterfaceStringTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("f", new Function() { + @Override + public String apply(String t) { + invoked.set(true); + return t; + } + }); + assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); + assertTrue(invoked.get()); + } + + // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. + @Test + public void functionalInterfaceObjectTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("c", new Consumer() { + @Override + public void accept(Object t) { + assertTrue(t instanceof ScriptObjectMirror); + assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); + invoked.set(true); + } + }); + e.eval("var x = 'xy'; x += 'z';c({a:x})"); + assertTrue(invoked.get()); + } + private static void checkProperty(final ScriptEngine e, final String name) throws ScriptException { final String value = System.getProperty(name); diff -r 6b55dd30a0ba -r 0388b3b63648 nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java Tue Jan 20 10:22:44 2015 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.test.models; + +public class OverloadedSetter { + private String color; + + public void setColor(final int x) { + this.color = Integer.toString(x); + } + + public void setColor(final String x) { + this.color = x; + } + + public String peekColor() { + return color; + } + + public void foo(final int x) { + } + + public String foo(final String x) { + return "boo"; + } +} diff -r 6b55dd30a0ba -r 0388b3b63648 test/lib/sun/hotspot/WhiteBox.java --- a/test/lib/sun/hotspot/WhiteBox.java Thu Jan 15 19:23:49 2015 -0800 +++ b/test/lib/sun/hotspot/WhiteBox.java Tue Jan 20 10:22:44 2015 -0800 @@ -84,6 +84,8 @@ return isClassAlive0(name.replace('.', '/')); } private native boolean isClassAlive0(String name); + public native boolean isMonitorInflated(Object obj); + public native void forceSafepoint(); // JVMTI public native void addToBootstrapClassLoaderSearch(String segment); diff -r 6b55dd30a0ba -r 0388b3b63648 test/lib/sun/hotspot/code/BlobType.java --- a/test/lib/sun/hotspot/code/BlobType.java Thu Jan 15 19:23:49 2015 -0800 +++ b/test/lib/sun/hotspot/code/BlobType.java Tue Jan 20 10:22:44 2015 -0800 @@ -32,11 +32,11 @@ public enum BlobType { // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) - MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), + MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'", "NonProfiledCodeHeapSize"), // Execution level 2 and 3 (profiled) nmethods - MethodProfiled(1, "CodeHeap 'profiled nmethods'"), + MethodProfiled(1, "CodeHeap 'profiled nmethods'", "ProfiledCodeHeapSize"), // Non-nmethods like Buffers, Adapters and Runtime Stubs - NonNMethod(2, "CodeHeap 'non-nmethods'") { + NonNMethod(2, "CodeHeap 'non-nmethods'", "NonNMethodCodeHeapSize") { @Override public boolean allowTypeWhenOverflow(BlobType type) { return super.allowTypeWhenOverflow(type) @@ -44,14 +44,16 @@ } }, // All types (No code cache segmentation) - All(3, "CodeCache"); + All(3, "CodeCache", "ReservedCodeCacheSize"); public final int id; - private final String beanName; + public final String sizeOptionName; + public final String beanName; - private BlobType(int id, String beanName) { + private BlobType(int id, String beanName, String sizeOptionName) { this.id = id; this.beanName = beanName; + this.sizeOptionName = sizeOptionName; } public MemoryPoolMXBean getMemoryPool() { @@ -87,4 +89,8 @@ } return result; } + + public long getSize() { + return WhiteBox.getWhiteBox().getUintxVMFlag(sizeOptionName); + } }