# HG changeset patch # User duke # Date 1499278503 -7200 # Node ID 0df4b242ce77922d06f0ca386242fbb2b5ec0015 # Parent c9c4b9563018c009b323b570c191a87d9f319018# Parent a820c88cb97b56f30ce7f49853b1c86b7fd856cb Merge diff -r c9c4b9563018 -r 0df4b242ce77 .hgtags-top-repo --- a/.hgtags-top-repo Thu Jan 15 13:09:43 2015 -0800 +++ b/.hgtags-top-repo Wed Jul 05 20:15:03 2017 +0200 @@ -288,3 +288,4 @@ 02ee8c65622e8bd97496d584e22fc7dcf0edc4ae jdk9-b43 8994f5d87b3bb5e8d317d4e8ccb326da1a73684a jdk9-b44 3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45 +12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 common/autoconf/configure --- a/common/autoconf/configure Thu Jan 15 13:09:43 2015 -0800 +++ b/common/autoconf/configure Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 common/bin/compare.sh --- a/common/bin/compare.sh Thu Jan 15 13:09:43 2015 -0800 +++ b/common/bin/compare.sh Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 corba/.hgtags --- a/corba/.hgtags Thu Jan 15 13:09:43 2015 -0800 +++ b/corba/.hgtags Wed Jul 05 20:15:03 2017 +0200 @@ -288,3 +288,4 @@ 9645e35616b60c5c07b4fdf11a132afc8081dfa8 jdk9-b43 1f57bd728c9e6865ccb9d43ccd80a1c11230a32f jdk9-b44 9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45 +326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 hotspot/.hgtags --- a/hotspot/.hgtags Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/.hgtags Wed Jul 05 20:15:03 2017 +0200 @@ -448,3 +448,4 @@ 65a9747147b8090037541040ba67156ec914db6a jdk9-b43 43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44 5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45 +a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 hotspot/agent/make/Makefile --- a/hotspot/agent/make/Makefile Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/agent/make/Makefile Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/agent/src/os/linux/LinuxDebuggerLocal.c --- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/agent/src/os/linux/symtab.c --- a/hotspot/agent/src/os/linux/symtab.c Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/agent/src/os/linux/symtab.c Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Wed Jul 05 20:15:03 2017 +0200 @@ -34,6 +34,6 @@ } public boolean isBigEndian() { - return true; + return "big".equals(System.getProperty("sun.cpu.endian")); } } diff -r c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/make/aix/makefiles/ppc64.make --- a/hotspot/make/aix/makefiles/ppc64.make Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/make/aix/makefiles/ppc64.make Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/make/aix/makefiles/xlc.make --- a/hotspot/make/aix/makefiles/xlc.make Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/make/aix/makefiles/xlc.make Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/make/linux/makefiles/sa.make --- a/hotspot/make/linux/makefiles/sa.make Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/make/linux/makefiles/sa.make Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/make/sa.files --- a/hotspot/make/sa.files Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/make/sa.files Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/ci/ciInstanceKlass.cpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/ci/ciInstanceKlass.hpp --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/stringTable.cpp --- a/hotspot/src/share/vm/classfile/stringTable.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/stringTable.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/stringTable.hpp --- a/hotspot/src/share/vm/classfile/stringTable.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/stringTable.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/symbolTable.hpp --- a/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/code/codeCache.hpp --- a/hotspot/src/share/vm/code/codeCache.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/memory/metaspaceShared.cpp --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/memory/metaspaceShared.hpp --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/memory/universe.hpp --- a/hotspot/src/share/vm/memory/universe.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/fieldStreams.hpp --- a/hotspot/src/share/vm/oops/fieldStreams.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/klassVtable.cpp --- a/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/klassVtable.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/method.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/methodData.cpp --- a/hotspot/src/share/vm/oops/methodData.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/methodData.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/oops/methodData.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/c2compiler.cpp --- a/hotspot/src/share/vm/opto/c2compiler.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2compiler.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/c2compiler.hpp --- a/hotspot/src/share/vm/opto/c2compiler.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/c2compiler.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/callnode.hpp --- a/hotspot/src/share/vm/opto/callnode.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/compile.cpp --- a/hotspot/src/share/vm/opto/compile.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/macroArrayCopy.cpp --- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/matcher.hpp --- a/hotspot/src/share/vm/opto/matcher.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/matcher.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/opto/parse1.cpp --- a/hotspot/src/share/vm/opto/parse1.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/opto/parse1.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/virtualspace.cpp --- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/virtualspace.hpp --- a/hotspot/src/share/vm/runtime/virtualspace.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/runtime/vm_operations.hpp --- a/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -100,6 +100,7 @@ template(RotateGCLog) \ template(WhiteBoxOperation) \ template(ClassLoaderStatsOperation) \ + template(DumpHashtable) \ template(MarkActiveNMethods) \ template(PrintCompileQueue) \ template(PrintCodeList) \ diff -r c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/utilities/globalDefinitions.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/TEST.groups Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java --- a/hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/ciReplay/TestSA.sh --- a/hotspot/test/compiler/ciReplay/TestSA.sh Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/ciReplay/TestSA.sh Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/ciReplay/common.sh --- a/hotspot/test/compiler/ciReplay/common.sh Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/ciReplay/common.sh Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/testlibrary/CompilerUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java --- a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/testlibrary/rtm/BusyLock.java --- a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java --- a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java --- a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java --- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java --- a/hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/gc/g1/TestGCLogMessages.java --- a/hotspot/test/gc/g1/TestGCLogMessages.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/gc/g1/TestGCLogMessages.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/BadObjectClass/Object.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/BadObjectClass/Object.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/CompressedOops/UseCompressedOops.java --- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/stress/gc/TestGCOld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/stress/gc/TestGCOld.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/Bar.java --- a/hotspot/test/testlibrary/ctw/test/Bar.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/ClassesDirTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/ClassesListTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/CtwTest.java --- a/hotspot/test/testlibrary/ctw/test/CtwTest.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/Foo.java --- a/hotspot/test/testlibrary/ctw/test/Foo.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/JarDirTest.java --- a/hotspot/test/testlibrary/ctw/test/JarDirTest.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/JarsTest.java --- a/hotspot/test/testlibrary/ctw/test/JarsTest.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary/ctw/test/classes.lst --- a/hotspot/test/testlibrary/ctw/test/classes.lst Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Jan 15 13:09:43 2015 -0800 +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/.hgtags --- a/jaxp/.hgtags Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/.hgtags Wed Jul 05 20:15:03 2017 +0200 @@ -288,3 +288,4 @@ 40b242363040229a05224fbc5dc203a3f46a8f8f jdk9-b43 0cb0844b58924d6086d2850c22087d06679d5eef jdk9-b44 0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45 +74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java --- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java Thu Jan 15 13:09:43 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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java --- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java --- a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jdk/.hgtags --- a/jdk/.hgtags Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/.hgtags Wed Jul 05 20:15:03 2017 +0200 @@ -288,3 +288,4 @@ 8c6ad41974f9ab6c33d544b088648314963f2a50 jdk9-b43 8cc4dc300041eb70a7a40e4b2431a8f4d4965ea4 jdk9-b44 9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45 +efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/java/io/BufferedWriter.java --- a/jdk/src/java.base/share/classes/java/io/BufferedWriter.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/io/BufferedWriter.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 @@ -73,12 +73,6 @@ private static int defaultCharBufferSize = 8192; /** - * Line separator string. This is the value of the line.separator - * property at the moment that the stream was created. - */ - private String lineSeparator; - - /** * Creates a buffered character-output stream that uses a default-sized * output buffer. * @@ -105,9 +99,6 @@ cb = new char[sz]; nChars = sz; nextChar = 0; - - lineSeparator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("line.separator")); } /** Checks to make sure that the stream has not been closed */ @@ -240,7 +231,7 @@ * @exception IOException If an I/O error occurs */ public void newLine() throws IOException { - write(lineSeparator); + write(System.lineSeparator()); } /** diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/java/io/PrintWriter.java --- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, 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 @@ -69,12 +69,6 @@ private PrintStream psOut = null; /** - * Line separator string. This is the value of the line.separator - * property at the moment that the stream was created. - */ - private final String lineSeparator; - - /** * Returns a charset object for the given charset name. * @throws NullPointerException is csn is null * @throws UnsupportedEncodingException if the charset is not supported @@ -113,8 +107,6 @@ super(out); this.out = out; this.autoFlush = autoFlush; - lineSeparator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("line.separator")); } /** @@ -477,7 +469,7 @@ try { synchronized (lock) { ensureOpen(); - out.write(lineSeparator); + out.write(System.lineSeparator()); if (autoFlush) out.flush(); } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/java/lang/String.java --- a/jdk/src/java.base/share/classes/java/lang/String.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/String.java Wed Jul 05 20:15:03 2017 +0200 @@ -135,7 +135,7 @@ * unnecessary since Strings are immutable. */ public String() { - this.value = new char[0]; + this.value = "".value; } /** @@ -175,7 +175,7 @@ * not affect the newly created string. * * @param value - * Array that is the source of characters + * Array that is the source of characters * * @param offset * The initial offset @@ -191,8 +191,14 @@ if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } - if (count < 0) { - throw new StringIndexOutOfBoundsException(count); + if (count <= 0) { + if (count < 0) { + throw new StringIndexOutOfBoundsException(count); + } + if (offset <= value.length) { + this.value = "".value; + return; + } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { @@ -233,8 +239,14 @@ if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } - if (count < 0) { - throw new StringIndexOutOfBoundsException(count); + if (count <= 0) { + if (count < 0) { + throw new StringIndexOutOfBoundsException(count); + } + if (offset <= codePoints.length) { + this.value = "".value; + return; + } } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { @@ -246,11 +258,11 @@ // Pass 1: Compute precise size of char[] int n = count; for (int i = offset; i < end; i++) { - int c = codePoints[i]; - if (Character.isBmpCodePoint(c)) - continue; - else if (Character.isValidCodePoint(c)) - n++; + int c = codePoints[i]; + if (Character.isBmpCodePoint(c)) + continue; + else if (Character.isValidCodePoint(c)) + n++; else throw new IllegalArgumentException(Integer.toString(c)); } @@ -783,7 +795,7 @@ * subarray of {@code dst} starting at index {@code dstBegin} * and ending at index: *
-     *     dstbegin + (srcEnd-srcBegin) - 1
+     *     dstBegin + (srcEnd-srcBegin) - 1
      * 
* * @param srcBegin index of the first character in the string @@ -828,7 +840,7 @@ * dst} starting at index {@code dstBegin} and ending at index: * *
-     *     dstbegin + (srcEnd-srcBegin) - 1
+     *     dstBegin + (srcEnd-srcBegin) - 1
      * 
* * @deprecated This method does not properly convert characters into diff -r c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/java/util/stream/Collectors.java --- a/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/java/util/stream/Collectors.java Wed Jul 05 20:15:03 2017 +0200 @@ -990,7 +990,7 @@ * function. * *

There are no guarantees on the type, mutability, or serializability - * of the {@code Map} or {@code List} objects returned, or of the + * of the {@code ConcurrentMap} or {@code List} objects returned, or of the * thread-safety of the {@code List} objects returned. * @implSpec * This produces a result similar to: @@ -1028,6 +1028,9 @@ * produces a result of type {@code D}. The resulting collector produces a * {@code Map}. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * *

For example, to compute the set of last names of people in each city, * where the city names are sorted: *

{@code
@@ -1143,7 +1146,8 @@
      * {@code Map>}.
      *
      * There are no guarantees on the type, mutability,
-     * serializability, or thread-safety of the {@code Map} returned.
+     * serializability, or thread-safety of the {@code Map} or {@code List}
+     * returned.
      *
      * @param  the type of the input elements
      * @param predicate a predicate used for classifying input elements
@@ -1212,6 +1216,9 @@
      * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
      * instead.
      *
+     * 

There are no guarantees on the type, mutability, serializability, + * or thread-safety of the {@code Map} returned. + * * @apiNote * It is common for either the key or the value to be the input elements. * In this case, the utility method @@ -1271,6 +1278,9 @@ * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * + *

There are no guarantees on the type, mutability, serializability, + * or thread-safety of the {@code Map} returned. + * * @apiNote * There are multiple ways to deal with collisions between multiple elements * mapping to the same key. The other forms of {@code toMap} simply use @@ -1382,6 +1392,9 @@ * may have duplicates, use * {@link #toConcurrentMap(Function, Function, BinaryOperator)} instead. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * * @apiNote * It is common for either the key or the value to be the input elements. * In this case, the utility method @@ -1436,6 +1449,9 @@ * the value mapping function is applied to each equal element, and the * results are merged using the provided merging function. * + *

There are no guarantees on the type, mutability, or serializability + * of the {@code ConcurrentMap} returned. + * * @apiNote * There are multiple ways to deal with collisions between multiple elements * mapping to the same key. The other forms of {@code toConcurrentMap} simply use diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java --- a/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/x509/PolicyConstraintsExtension.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -27,9 +27,7 @@ import java.io.IOException; import java.io.OutputStream; -import java.security.cert.CertificateException; import java.util.Enumeration; -import java.util.Vector; import sun.security.util.*; @@ -111,7 +109,7 @@ */ public PolicyConstraintsExtension(int require, int inhibit) throws IOException { - this(Boolean.FALSE, require, inhibit); + this(Boolean.TRUE, require, inhibit); } /** @@ -202,7 +200,7 @@ DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyConstraints_Id; - critical = false; + critical = true; encodeThis(); } super.encode(tmp); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java --- a/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/share/classes/sun/security/x509/PolicyMappingsExtension.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -92,7 +92,7 @@ throws IOException { this.maps = map; this.extensionId = PKIXExtensions.PolicyMappings_Id; - this.critical = false; + this.critical = true; encodeThis(); } @@ -100,8 +100,8 @@ * Create a default PolicyMappingsExtension. */ public PolicyMappingsExtension() { - extensionId = PKIXExtensions.KeyUsage_Id; - critical = false; + extensionId = PKIXExtensions.PolicyMappings_Id; + critical = true; maps = new ArrayList(); } @@ -153,7 +153,7 @@ DerOutputStream tmp = new DerOutputStream(); if (extensionValue == null) { extensionId = PKIXExtensions.PolicyMappings_Id; - critical = false; + critical = true; encodeThis(); } super.encode(tmp); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/unix/classes/java/io/FileDescriptor.java --- a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -214,7 +214,7 @@ if (!closed) { closed = true; IOException ioe = null; - try (Closeable c = releaser) { + try (releaser) { if (otherParents != null) { for (Closeable referent : otherParents) { try { diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.base/windows/classes/java/io/FileDescriptor.java --- a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -212,7 +212,7 @@ if (!closed) { closed = true; IOException ioe = null; - try (Closeable c = releaser) { + try (releaser) { if (otherParents != null) { for (Closeable referent : otherParents) { try { diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java --- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -224,6 +224,7 @@ String hostname = null; // host name of server (no brackets // for IPv6 literals) LdapClient clnt = null; // connection handle + private boolean reconnect = false; // indicates that re-connect requested Hashtable envprops = null; // environment properties of context int handleReferrals = DEFAULT_REFERRAL_MODE; // how referral is handled boolean hasLdapsScheme = false; // true if the context was created @@ -2663,6 +2664,7 @@ } sharable = false; // can't share with existing contexts + reconnect = true; ensureOpen(); // open or reauthenticated } @@ -2739,7 +2741,7 @@ try { boolean initial = (clnt == null); - if (initial) { + if (initial || reconnect) { ldapVersion = (ver != null) ? Integer.parseInt(ver) : DEFAULT_LDAP_VERSION; @@ -2767,6 +2769,7 @@ // Required for SASL client identity envprops); + reconnect = false; /** * Pooled connections are preauthenticated; diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java --- a/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Wed Jul 05 20:15:03 2017 +0200 @@ -37,12 +37,13 @@ import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; import java.security.*; import java.security.cert.Certificate; import java.security.cert.*; +import javax.naming.CommunicationException; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; import javax.security.auth.x500.X500Principal; import sun.misc.HexDumpEncoder; @@ -160,7 +161,12 @@ /** * The JNDI directory context. */ - private DirContext ctx; + private LdapContext ctx; + + /** + * Flag indicating that communication error occurred. + */ + private boolean communicationError = false; /** * Flag indicating whether we should prefetch CRLs. @@ -218,6 +224,11 @@ certStoreCache = Cache.newSoftMemoryCache(185); static synchronized CertStore getInstance(LDAPCertStoreParameters params) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { + // if necessary, convert params to SunLDAPCertStoreParameters because + // LDAPCertStoreParameters does not override equals() and hashCode() + if (! (params instanceof SunLDAPCertStoreParameters)) { + params = new SunLDAPCertStoreParameters(params.getServerName(), params.getPort()); + } CertStore lcs = certStoreCache.get(params); if (lcs == null) { lcs = CertStore.getInstance("LDAP", params); @@ -256,7 +267,7 @@ } try { - ctx = new InitialDirContext(env); + ctx = new InitialLdapContext(env, null); /* * By default, follow referrals unless application has * overridden property in an application resource file. @@ -369,8 +380,17 @@ valueMap = new HashMap<>(8); String[] attrIds = requestedAttributes.toArray(STRING0); Attributes attrs; + + if (communicationError) { + ctx.reconnect(null); + communicationError = false; + } + try { attrs = ctx.getAttributes(name, attrIds); + } catch (CommunicationException ce) { + communicationError = true; + throw ce; } catch (NameNotFoundException e) { // name does not exist on this LDAP server // treat same as not attributes found @@ -884,7 +904,12 @@ SunLDAPCertStoreParameters() { super(); } + @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof LDAPCertStoreParameters)) { return false; } @@ -892,6 +917,7 @@ return (getPort() == params.getPort() && getServerName().equalsIgnoreCase(params.getServerName())); } + @Override public int hashCode() { if (hashCode == 0) { int result = 17; diff -r c9c4b9563018 -r 0df4b242ce77 jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java --- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/src/jdk.deploy.osx/macosx/classes/apple/security/KeychainStore.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 @@ -911,6 +911,7 @@ return true; } + @SuppressWarnings("deprecation") private byte[] fetchPrivateKeyFromBag(byte[] privateKeyInfo) throws IOException, NoSuchAlgorithmException, CertificateException { byte[] returnValue = null; @@ -971,6 +972,7 @@ return returnValue; } + @SuppressWarnings("deprecation") private byte[] extractKeyData(DerInputStream stream) throws IOException, NoSuchAlgorithmException, CertificateException { diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/ProblemList.txt Wed Jul 05 20:15:03 2017 +0200 @@ -142,9 +142,6 @@ # 8058492 java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all -# 8058506 -java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java generic-all - ############################################################################ # jdk_jmx diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/TEST.groups --- a/jdk/test/TEST.groups Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/TEST.groups Wed Jul 05 20:15:03 2017 +0200 @@ -421,8 +421,7 @@ java/util/Collections/EmptyIterator.java \ java/util/concurrent/locks/Lock/TimedAcquireLeak.java \ java/util/jar/JarInputStream/ExtraFileInMetaInf.java \ - java/util/logging/AnonLoggerWeakRefLeak.sh \ - java/util/logging/LoggerWeakRefLeak.sh \ + java/util/logging/TestLoggerWeakRefLeak.java \ java/util/zip/3GBZipFiles.sh \ jdk/lambda/FDTest.java \ jdk/lambda/separate/Compiler.java \ diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Mac/EmptyByteBufferTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1998, 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 java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if MAC algorithms work fine with empty buffer + * @author Alexander Fomin + * @build Utils + * @run main EmptyByteBufferTest + */ +public class EmptyByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new EmptyByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[0]; + ByteBuffer buf = ByteBuffer.wrap(data); + + mac.update(buf); + mac.doFinal(); + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Mac/LargeByteBufferTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1998, 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 java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with large buffer + * @author Alexander Fomin + * @build Utils + * @run main LargeByteBufferTest + */ +public class LargeByteBufferTest implements MacTest { + + private static final int BUFFER_SIZE = 65535; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new LargeByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + // prepare buffer + byte[] data = new byte[BUFFER_SIZE]; + for (int i = 0; i < BUFFER_SIZE; i++) { + data[i] = (byte) (i % 256); + } + + ByteBuffer buf = ByteBuffer.wrap(data); + int limitBefore = buf.limit(); + + mac.update(buf); + mac.doFinal(); + + int limitAfter = buf.limit(); + int positonAfter = buf.position(); + + if (limitAfter != limitBefore) { + System.out.println("limit after = " + limitAfter); + System.out.println("limit before = " + limitBefore); + throw new RuntimeException("Test failed: " + + "limit of buffer has been chenged."); + } + + if (positonAfter != limitAfter) { + System.out.println("position after = " + positonAfter); + System.out.println("limit after = " + limitAfter); + throw new RuntimeException("Test failed: " + + "position of buffer isn't equal to its limit"); + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Mac/MacSameTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1998, 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 java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @build Utils + * @run main MacSameTest + */ +public class MacSameTest implements MacTest { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new MacSameTest()); + } + + @Override + public void doTest(String algo) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidKeyException { + Mac mac; + try { + mac = Mac.getInstance(algo, "SunJCE"); + } catch (NoSuchAlgorithmException nsae) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Mac/NullByteBufferTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1998, 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 java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import javax.crypto.Mac; +import javax.crypto.SecretKey; + +/** + * @test + * @bug 8048603 + * @summary Checks if PBE algorithms work fine with null buffer + * @author Alexander Fomin + * @build Utils + * @run main NullByteBufferTest + */ +public class NullByteBufferTest implements MacTest { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + Utils.runTests(new NullByteBufferTest()); + } + + @Override + public void doTest(String alg) throws NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException { + SecretKey key = Utils.getSecretKeySpec(); + + // instantiate Mac object and init it with a SecretKey + Mac mac = Mac.getInstance(alg, "SunJCE"); + mac.init(key); + + try { + ByteBuffer buf = null; + mac.update(buf); + mac.doFinal(); + throw new RuntimeException( + "Expected IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + System.out.println("Expected IllegalArgumentException thrown: " + + e); + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/com/sun/crypto/provider/Mac/Utils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/crypto/provider/Mac/Utils.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 1998, 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 java.security.SecureRandom; +import javax.crypto.spec.SecretKeySpec; + +/** + * Helper class. + */ +class Utils { + + static final int KEY_SIZE = 70; + + static final String[] MAC_ALGOS = {"HmacMD5", "HmacSHA1", "HmacSHA224", + "HmacSHA256", "HmacSHA384", "HmacSHA512"}; + + /** + * Get SecretKeySpec. + */ + static SecretKeySpec getSecretKeySpec() { + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + return new SecretKeySpec(keyVal, "HMAC"); + } + + static void runTests(MacTest... tests) { + boolean success = true; + for (MacTest test : tests) { + success &= runTest(test); + } + + if (success) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("Test failed"); + } + } + + private static boolean runTest(MacTest test) { + boolean success = true; + for (String alg : MAC_ALGOS) { + try { + System.out.println("Test " + alg); + test.doTest(alg); + } catch (Exception e) { + System.out.println("Unexpected exception:"); + e.printStackTrace(); + success = false; + } + } + + return success; + } +} + +interface MacTest { + void doTest(String alg) throws Exception; +} \ No newline at end of file diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/lang/instrument/IsModifiableClassAgent.java --- a/jdk/test/java/lang/instrument/IsModifiableClassAgent.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/lang/instrument/IsModifiableClassAgent.java Wed Jul 05 20:15:03 2017 +0200 @@ -23,6 +23,7 @@ /** * @test + * @ignore JDK-8068162 * @bug 6331574 * @summary test isModifiableClass * @author Robert Field, Sun Microsystems diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java --- a/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/lang/invoke/LFCaching/LFGarbageCollectedTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -30,11 +30,13 @@ * @build TestMethods * @build LambdaFormTestCase * @build LFGarbageCollectedTest - * @run main/othervm LFGarbageCollectedTest + * @run main/othervm -Xmx64m -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+HeapDumpOnOutOfMemoryError -DHEAP_DUMP=false LFGarbageCollectedTest */ import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.InvocationTargetException; import java.util.EnumSet; @@ -44,6 +46,7 @@ * Lambda forms garbage collection test class. */ public final class LFGarbageCollectedTest extends LambdaFormTestCase { + private static boolean HEAP_DUMP = Boolean.getBoolean("HEAP_DUMP"); /** * Constructor for a lambda forms garbage collection test case. @@ -55,37 +58,86 @@ super(testMethod); } + PhantomReference ph; + ReferenceQueue rq = new ReferenceQueue(); + MethodType mtype; + Map data; + @Override public void doTest() { try { - Map data = getTestMethod().getTestCaseData(); + TestMethods testCase = getTestMethod(); + data = testCase.getTestCaseData(); MethodHandle adapter; try { - adapter = getTestMethod().getTestCaseMH(data, TestMethods.Kind.ONE); + adapter = testCase.getTestCaseMH(data, TestMethods.Kind.ONE); } catch (NoSuchMethodException ex) { throw new Error("Unexpected exception: ", ex); } - Object lambdaForm = LambdaFormTestCase.INTERNAL_FORM.invoke(adapter); + mtype = adapter.type(); + Object lambdaForm = INTERNAL_FORM.invoke(adapter); if (lambdaForm == null) { throw new Error("Unexpected error: Lambda form of the method handle is null"); } - ReferenceQueue rq = new ReferenceQueue(); - PhantomReference ph = new PhantomReference(lambdaForm, rq); + + String debugName = (String)DEBUG_NAME.get(lambdaForm); + if (debugName != null && debugName.startsWith("identity_")) { + // Ignore identity_* LambdaForms. + return; + } + + ph = new PhantomReference(lambdaForm, rq); lambdaForm = null; - data = null; adapter = null; - for (int i = 0; i < 1000 && !ph.isEnqueued(); i++) { - System.gc(); - } - if (!ph.isEnqueued()) { - throw new AssertionError("Error: Lambda form is not garbage collected"); - } + + collectLambdaForm(); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new Error("Unexpected exception: ", ex); } } + + private void collectLambdaForm() throws IllegalAccessException { + // Usually, 2 System.GCs are necessary to enqueue a SoftReference. + System.gc(); + System.gc(); + + Reference ref = null; + for (int i = 0; i < 10; i++) { + try { + ref = rq.remove(1000); + } catch (InterruptedException e) { + /* ignore */ + } + if (ref != null) { + break; + } + System.gc(); // If the reference hasn't been queued yet, trigger one more GC. + } + + if (ref == null) { + dumpTestData(); + System.err.println("Method type: " + mtype); + System.err.println("LambdaForm: " + REF_FIELD.get(ph)); + + if (HEAP_DUMP) { + // Trigger OOM to force heap dump for post-mortem analysis. + val = new long[1_000_000_000]; + } + throw new AssertionError("Error: LambdaForm is not garbage collected"); + }; + } + + private void dumpTestData() { + System.err.println("Test case: " + getTestMethod()); + for (String s : data.keySet()) { + System.err.printf("\t%20s => %s\n", s, data.get(s)); + } + } + + private static long[] val; + /** * Main routine for lambda forms garbage collection test. * @@ -101,7 +153,9 @@ TestMethods.IDENTITY, TestMethods.CONSTANT, TestMethods.ARRAY_ELEMENT_GETTER, - TestMethods.ARRAY_ELEMENT_SETTER)); + TestMethods.ARRAY_ELEMENT_SETTER, + TestMethods.EXACT_INVOKER, + TestMethods.INVOKER)); LambdaFormTestCase.runTests(LFGarbageCollectedTest::new, testMethods); } } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java --- a/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/lang/invoke/LFCaching/LambdaFormTestCase.java Wed Jul 05 20:15:03 2017 +0200 @@ -23,9 +23,11 @@ import com.oracle.testlibrary.jsr292.Helper; import com.sun.management.HotSpotDiagnosticMXBean; - +import java.lang.invoke.MethodHandle; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; +import java.lang.ref.Reference; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; @@ -42,8 +44,6 @@ */ public abstract class LambdaFormTestCase { - private final static String METHOD_HANDLE_CLASS_NAME = "java.lang.invoke.MethodHandle"; - private final static String INTERNAL_FORM_METHOD_NAME = "internalForm"; private static final double ITERATIONS_TO_CODE_CACHE_SIZE_RATIO = 45 / (128.0 * 1024 * 1024); private static final long TIMEOUT = Helper.IS_THOROUGH ? 0L : (long) (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) * 0.9); @@ -53,6 +53,8 @@ * used to get a lambda form from a method handle. */ protected final static Method INTERNAL_FORM; + protected final static Field DEBUG_NAME; + protected final static Field REF_FIELD; private static final List gcInfo; private static long gcCount() { @@ -61,9 +63,14 @@ static { try { - Class mhClass = Class.forName(METHOD_HANDLE_CLASS_NAME); - INTERNAL_FORM = mhClass.getDeclaredMethod(INTERNAL_FORM_METHOD_NAME); + INTERNAL_FORM = MethodHandle.class.getDeclaredMethod("internalForm"); INTERNAL_FORM.setAccessible(true); + + DEBUG_NAME = Class.forName("java.lang.invoke.LambdaForm").getDeclaredField("debugName"); + DEBUG_NAME.setAccessible(true); + + REF_FIELD = Reference.class.getDeclaredField("referent"); + REF_FIELD.setAccessible(true); } catch (Exception ex) { throw new Error("Unexpected exception: ", ex); } @@ -138,6 +145,10 @@ testCase.getTestMethod().name); testCase.doTest(); System.err.println("PASSED"); + } catch (OutOfMemoryError e) { + // Don't swallow OOME so a heap dump can be created. + System.err.println("FAILED"); + throw e; } catch (Throwable t) { t.printStackTrace(); System.err.printf("FAILED. Caused by %s%n", t.getMessage()); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java --- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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,6 +32,7 @@ * * @library /lib/testlibrary/ * @build jdk.testlibrary.* CollectionUsageThreshold MemoryUtil RunUtil + * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" * @run main/timeout=300 CollectionUsageThreshold */ diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java --- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -32,6 +32,7 @@ * * @library /lib/testlibrary/ * @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil + * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" * @run main/timeout=600 LowMemoryTest */ diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/net/DatagramSocket/InheritHandle.java --- a/jdk/test/java/net/DatagramSocket/InheritHandle.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/java/net/DatagramSocket/InheritHandle.java Wed Jul 05 20:15:03 2017 +0200 @@ -22,27 +22,51 @@ */ /* @test - * @bug 4945514 + * @bug 4945514 8042581 * @summary DatagramSocket should make handle not inherited */ -import java.net.*; +import java.net.BindException; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; public class InheritHandle { + private static final long SLEEPTIME_MS = 1000L; + public static void main(String[] args) throws Exception { - DatagramSocket sock = new DatagramSocket (0); - sock.setReuseAddress(true); - int port = sock.getLocalPort(); + int port; + try (DatagramSocket sock = new DatagramSocket(0);) { + sock.setReuseAddress(true); + port = sock.getLocalPort(); + + /** + * spawn a child to check whether handle passed to it or not; it + * shouldn't + */ + Runtime.getRuntime().exec("sleep 10"); + } - /** - * spawn a child to check whether handle passed to it or not; - * it shouldn't - */ - Runtime.getRuntime().exec ("sleep 10"); + try (DatagramSocket sock = new DatagramSocket(null);) { + sock.setReuseAddress(true); + int retries = 0; + boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + InetSocketAddress addr = new InetSocketAddress(port); + while (true) { + try { + sock.bind(addr); + break; + } catch (BindException e) { + if (isWindows && retries++ < 5) { + Thread.sleep(SLEEPTIME_MS); + System.out.println("BindException \"" + e.getMessage() + "\", retrying..."); + continue; + } else { + throw e; + } + } + } - sock.close(); - sock = new DatagramSocket (null); - sock.setReuseAddress(true); - sock.bind(new InetSocketAddress(port)); + } } } + diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java Thu Jan 15 13:09:43 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010, 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.logging.*; - -public class AnonLoggerWeakRefLeak extends SimpleApplication { - // The test driver script will allow this program to run until we - // reach DEFAULT_LOOP_TIME or a decrease in instance counts is - // observed. For this particular WeakReference leak, the count - // was always observed to be increasing so if we get a decreasing - // count, then the leak is fixed in the bits being tested. - // Two minutes has been enough time to observe a decrease in - // fixed bits on overloaded systems, but the test will likely - // finish more quickly. - public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - - // execute the AnonLoggerWeakRefLeak app work - public void doMyAppWork(String[] args) throws Exception { - int loop_time = 0; - int max_loop_time = DEFAULT_LOOP_TIME; - - // args[0] is the port-file - if (args.length < 2) { - System.out.println("INFO: using default time of " - + max_loop_time + " seconds."); - } else { - try { - max_loop_time = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - throw new RuntimeException("Error: '" + args[1] - + "': is not a valid seconds value."); - } - } - - long count = 0; - long now = 0; - long startTime = System.currentTimeMillis(); - - while (now < (startTime + (max_loop_time * 1000))) { - if ((count % 1000) == 0) { - // Print initial call count to let caller know that - // we're up and running and then periodically - System.out.println("INFO: call count = " + count); - } - - for (int i = 0; i < 100; i++) { - // this Logger call is leaking a WeakReference in Logger.kids - java.util.logging.Logger.getAnonymousLogger(); - count++; - } - - try { - // delay for 1/10 of a second to avoid CPU saturation - Thread.sleep(100); - } catch (InterruptedException ie) { - // ignore any exceptions - } - - now = System.currentTimeMillis(); - } - - System.out.println("INFO: final loop count = " + count); - } - - public static void main(String[] args) throws Exception { - AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); - - SimpleApplication.setMyApp(myApp); - - SimpleApplication.main(args); - } -} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh Thu Jan 15 13:09:43 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6942989 -# @summary Check for WeakReference leak in anonymous Logger objects -# @author Daniel D. Daugherty -# -# @library ../../../sun/tools/common -# @build SimpleApplication ShutdownSimpleApplication -# @build AnonLoggerWeakRefLeak -# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh - -# The timeout is: 2 minutes for infrastructure and 2 minutes for the test -# - -. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh -. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh - - -TEST_NAME="AnonLoggerWeakRefLeak" -TARGET_CLASS="java\.lang\.ref\.WeakReference" - - -# MAIN begins here -# - -seconds= -if [ "$#" -gt 0 ]; then - seconds="$1" -fi - -# see if this version of jmap supports the '-histo:live' option -jmap_option="-histo:live" -set +e -"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 -status="$?" -set -e -if [ "$status" != 0 ]; then - # usage message doesn't show ':live' option - - if $isWindows; then - # If SA isn't present, then jmap gives a different usage message - # that doesn't show the ':live' option. However, that's a bug that - # is covered by 6971851 so we try using the option just to be sure. - # For some reason, this problem has only been seen on OpenJDK6 on - # Windows. Not sure why. - set +e - # Note: Don't copy this code to try probing process 0 on Linux; it - # will kill the process group in strange ways. - "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - # Usage message generated so flag the problem. - status=1 - else - # No usage message so clear the flag. - status=0 - fi - fi - - if [ "$status" != 0 ]; then - echo "WARNING: 'jmap $jmap_option' is not supported on this platform" - echo "WARNING: so this test cannot work reliably. Aborting!" - exit 0 - fi -fi - -# Start application and use TEST_NAME.port for coordination -startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds - -finished_early=false - -decreasing_cnt=0 -increasing_cnt=0 -loop_cnt=0 -prev_instance_cnt=0 - -MAX_JMAP_TRY_CNT=10 -jmap_retry_cnt=0 -loop_cnt_on_retry=0 - -while true; do - # see if the target process has finished its run and bail if it has - set +e - grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - break - fi - - # Output format for 'jmap -histo' in JDK1.5.0: - # - # <#bytes> <#instances> - # - # Output format for 'jmap -histo:live': - # - # : <#instances> <#bytes> - # - set +e - "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 - status="$?" - set -e - - if [ "$status" != 0 ]; then - echo "INFO: jmap exited with exit code = $status" - - # There are intermittent jmap failures; see 6498448. - # - # So far the following have been observed in a jmap call - # that was not in a race with target process termination: - # - # (Solaris specific, 2nd sample) - # : Unable to open door: target process not responding or HotSpot VM not loaded - # The -F option can be used when the target process is not responding - # - # (on Solaris so far) - # java.io.IOException - # - # (on Solaris so far, 1st sample) - # : Permission denied - # - sed 's/^/INFO: /' "$TEST_NAME.jmap" - - if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then - # loop count hasn't changed - jmap_retry_cnt=`expr $jmap_retry_cnt + 1` - else - # loop count has changed so remember it - jmap_retry_cnt=1 - loop_cnt_on_retry="$loop_cnt" - fi - - # This is '-ge' because we have the original attempt plus - # MAX_JMAP_TRY_CNT - 1 retries. - if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then - echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ - "without making any progress." - echo "FAIL: jmap is unable to take any samples." >&2 - killApplication - exit 2 - fi - - # short delay and try again - # Note: sleep 1 didn't help with ": Permission denied" - sleep 2 - echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." - continue - fi - - set +e - instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ - "$TEST_NAME.jmap" \ - | sed ' - # strip leading whitespace; does nothing in JDK1.5.0 - s/^'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip field - s/'"${PATTERN_WS}"'.*// - '` - set -e - if [ -z "$instance_cnt" ]; then - echo "INFO: instance count is unexpectedly empty" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no sample was found." - echo "INFO: There is likely a problem with the sed filter." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." - echo "FAIL: cannot find the instance count value." >&2 - killApplication - exit 2 - fi - else - echo "INFO: instance_cnt = $instance_cnt" - - if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then - increasing_cnt=`expr $increasing_cnt + 1` - else - # actually decreasing or the same - decreasing_cnt=`expr $decreasing_cnt + 1` - - # For this particular WeakReference leak, the count was - # always observed to be increasing so if we get a decreasing - # or the same count, then the leak is fixed in the bits - # being tested. - echo "INFO: finishing early due to non-increasing instance count." - finished_early=true - killApplication - break - fi - prev_instance_cnt="$instance_cnt" - fi - - # delay between samples - sleep 5 - - loop_cnt=`expr $loop_cnt + 1` -done - -if [ $finished_early = false ]; then - stopApplication "$TEST_NAME.port" - waitForApplication -fi - -echo "INFO: $TEST_NAME has finished running." -echo "INFO: increasing_cnt = $increasing_cnt" -echo "INFO: decreasing_cnt = $decreasing_cnt" -if [ "$jmap_retry_cnt" -gt 0 ]; then - echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" -fi - -if [ "$loop_cnt" = 0 ]; then - echo "FAIL: jmap is unable to take any samples." >&2 - exit 2 -fi - -echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" -if [ "$decreasing_cnt" = 0 ]; then - echo "INFO: is always increasing." - echo "FAIL: This indicates that there is a memory leak." >&2 - exit 2 -fi - -echo "INFO: is not always increasing." -echo "PASS: This indicates that there is not a memory leak." -exit 0 diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/util/logging/LoggerWeakRefLeak.java --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.java Thu Jan 15 13:09:43 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2010, 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.logging.*; - -public class LoggerWeakRefLeak extends SimpleApplication { - // The test driver script will allow this program to run until we - // reach DEFAULT_LOOP_TIME or a decrease in instance counts is - // observed. For these particular WeakReference leaks, the count - // was always observed to be increasing so if we get a decreasing - // count, then the leaks are fixed in the bits being tested. - // Two minutes has been enough time to observe a decrease in - // fixed bits on overloaded systems, but the test will likely - // finish more quickly. - public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - - // execute the LoggerWeakRefLeak app work - public void doMyAppWork(String[] args) throws Exception { - int loop_time = 0; - int max_loop_time = DEFAULT_LOOP_TIME; - - // args[0] is the port-file - if (args.length < 2) { - System.out.println("INFO: using default time of " - + max_loop_time + " seconds."); - } else { - try { - max_loop_time = Integer.parseInt(args[1]); - } catch (NumberFormatException nfe) { - throw new RuntimeException("Error: '" + args[1] - + "': is not a valid seconds value."); - } - } - - long count = 0; - int loggerCount = 0; - long now = 0; - long startTime = System.currentTimeMillis(); - - while (now < (startTime + (max_loop_time * 1000))) { - if ((count % 1000) == 0) { - // Print initial call count to let caller know that - // we're up and running and then periodically - System.out.println("INFO: call count = " + count); - } - - for (int i = 0; i < 100; i++) { - // This Logger call is leaking two different WeakReferences: - // - one in LogManager.LogNode - // - one in Logger.kids - java.util.logging.Logger.getLogger("logger-" + loggerCount); - count++; - if (++loggerCount >= 25000) { - // Limit the Logger namespace used by the test so - // the weak refs in LogManager.loggers that are - // being properly managed don't skew the counts - // by too much. - loggerCount = 0; - } - } - - try { - // delay for 1/10 of a second to avoid CPU saturation - Thread.sleep(100); - } catch (InterruptedException ie) { - // ignore any exceptions - } - - now = System.currentTimeMillis(); - } - - System.out.println("INFO: final loop count = " + count); - } - - public static void main(String[] args) throws Exception { - AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); - - SimpleApplication.setMyApp(myApp); - - SimpleApplication.main(args); - } -} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/util/logging/LoggerWeakRefLeak.sh --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.sh Thu Jan 15 13:09:43 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6942989 -# @summary Check for WeakReference leak in Logger objects -# @author Daniel D. Daugherty -# -# @library ../../../sun/tools/common -# @build SimpleApplication ShutdownSimpleApplication -# @build LoggerWeakRefLeak -# @run shell/timeout=240 LoggerWeakRefLeak.sh - -# The timeout is: 2 minutes for infrastructure and 2 minutes for the test -# - -. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh -. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh - - -TEST_NAME="LoggerWeakRefLeak" -TARGET_CLASS="java\.lang\.ref\.WeakReference" - - -# MAIN begins here -# - -seconds= -if [ "$#" -gt 0 ]; then - seconds="$1" -fi - -# see if this version of jmap supports the '-histo:live' option -jmap_option="-histo:live" -set +e -"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 -status="$?" -set -e -if [ "$status" != 0 ]; then - # usage message doesn't show ':live' option - - if $isWindows; then - # If SA isn't present, then jmap gives a different usage message - # that doesn't show the ':live' option. However, that's a bug that - # is covered by 6971851 so we try using the option just to be sure. - # For some reason, this problem has only been seen on OpenJDK6 on - # Windows. Not sure why. - set +e - # Note: Don't copy this code to try probing process 0 on Linux; it - # will kill the process group in strange ways. - "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - # Usage message generated so flag the problem. - status=1 - else - # No usage message so clear the flag. - status=0 - fi - fi - - if [ "$status" != 0 ]; then - echo "WARNING: 'jmap $jmap_option' is not supported on this platform" - echo "WARNING: so this test cannot work reliably. Aborting!" - exit 0 - fi -fi - -# Start application and use TEST_NAME.port for coordination -startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds - -finished_early=false - -decreasing_cnt=0 -increasing_cnt=0 -loop_cnt=0 -prev_instance_cnt=0 - -MAX_JMAP_TRY_CNT=10 -jmap_retry_cnt=0 -loop_cnt_on_retry=0 - -while true; do - # see if the target process has finished its run and bail if it has - set +e - grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 - status="$?" - set -e - if [ "$status" = 0 ]; then - break - fi - - # Output format for 'jmap -histo' in JDK1.5.0: - # - # <#bytes> <#instances> - # - # Output format for 'jmap -histo:live': - # - # : <#instances> <#bytes> - # - set +e - "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 - status="$?" - set -e - - if [ "$status" != 0 ]; then - echo "INFO: jmap exited with exit code = $status" - - # There are intermittent jmap failures; see 6498448. - # - # So far the following have been observed in a jmap call - # that was not in a race with target process termination: - # - # (Solaris specific, 2nd sample) - # : Unable to open door: target process not responding or HotSpot VM not loaded - # The -F option can be used when the target process is not responding - # - # (on Solaris so far) - # java.io.IOException - # - # (on Solaris so far, 1st sample) - # : Permission denied - # - sed 's/^/INFO: /' "$TEST_NAME.jmap" - - if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then - # loop count hasn't changed - jmap_retry_cnt=`expr $jmap_retry_cnt + 1` - else - # loop count has changed so remember it - jmap_retry_cnt=1 - loop_cnt_on_retry="$loop_cnt" - fi - - # This is '-ge' because we have the original attempt plus - # MAX_JMAP_TRY_CNT - 1 retries. - if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then - echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ - "without making any progress." - echo "FAIL: jmap is unable to take any samples." >&2 - killApplication - exit 2 - fi - - # short delay and try again - # Note: sleep 1 didn't help with ": Permission denied" - sleep 2 - echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." - continue - fi - - set +e - instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ - "$TEST_NAME.jmap" \ - | sed ' - # strip leading whitespace; does nothing in JDK1.5.0 - s/^'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// - # strip field - s/'"${PATTERN_WS}"'.*// - '` - set -e - if [ -z "$instance_cnt" ]; then - echo "INFO: instance count is unexpectedly empty" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no sample was found." - echo "INFO: There is likely a problem with the sed filter." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." - echo "FAIL: cannot find the instance count value." >&2 - killApplication - exit 2 - fi - else - echo "INFO: instance_cnt = $instance_cnt" - - if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then - increasing_cnt=`expr $increasing_cnt + 1` - else - # actually decreasing or the same - decreasing_cnt=`expr $decreasing_cnt + 1` - - # For these particular WeakReference leaks, the count was - # always observed to be increasing so if we get a decreasing - # or the same count, then the leaks are fixed in the bits - # being tested. - echo "INFO: finishing early due to non-increasing instance count." - finished_early=true - killApplication - break - fi - prev_instance_cnt="$instance_cnt" - fi - - # delay between samples - sleep 5 - - loop_cnt=`expr $loop_cnt + 1` -done - -if [ $finished_early = false ]; then - stopApplication "$TEST_NAME.port" - waitForApplication -fi - -echo "INFO: $TEST_NAME has finished running." -echo "INFO: increasing_cnt = $increasing_cnt" -echo "INFO: decreasing_cnt = $decreasing_cnt" -if [ "$jmap_retry_cnt" -gt 0 ]; then - echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" -fi - -if [ "$loop_cnt" = 0 ]; then - echo "FAIL: jmap is unable to take any samples." >&2 - exit 2 -fi - -echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" -if [ "$decreasing_cnt" = 0 ]; then - echo "INFO: is always increasing." - echo "FAIL: This indicates that there is a memory leak." >&2 - exit 2 -fi - -echo "INFO: is not always increasing." -echo "PASS: This indicates that there is not a memory leak." -exit 0 diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/java/util/logging/TestLoggerWeakRefLeak.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/logging/TestLoggerWeakRefLeak.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010, 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 java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static jdk.testlibrary.Asserts.assertGreaterThan; +import jdk.testlibrary.ProcessTools; + +import com.sun.tools.attach.AttachNotSupportedException; +import com.sun.tools.attach.VirtualMachine; + +import sun.tools.attach.HotSpotVirtualMachine; + +/* + * @test + * @bug 6942989 + * @summary Check for WeakReference leak in Logger and anonymous Logger objects + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main/othervm TestLoggerWeakRefLeak Logger + * @run main/othervm TestLoggerWeakRefLeak AnonymousLogger + */ +public class TestLoggerWeakRefLeak { + + private static final String TARGET_CLASS = "java.lang.ref.WeakReference"; + private static final int INSTANCE_COUNT = 100; + private static int loggerCount = 0; + + public static void main(String[] args) throws Exception { + if (args[0].equals("AnonymousLogger")) { + System.out.println("Test for WeakReference leak in AnonymousLogger object"); + testIfLeaking(TestLoggerWeakRefLeak::callAnonymousLogger); + } else { + System.out.println("Test for WeakReference leak in Logger object"); + testIfLeaking(TestLoggerWeakRefLeak::callLogger); + } + } + + /** + * For these particular WeakReference leaks, the count was always observed + * to be increasing so if decreasing or the same count is observed, + * then there is no leak. + */ + private static void testIfLeaking(Runnable callLogger) throws Exception { + long count = 0; + int instanceCount = 0; + int previousInstanceCount = 0; + int increasingCount = 0; + int decreasingCount = 0; + + while (true) { + callLogger.run(); + count += INSTANCE_COUNT; + + if ((count % 1000) == 0) { + System.out.println("call count = " + count); + + instanceCount = getInstanceCountFromHeapHisto(); + if (instanceCount > previousInstanceCount) { + increasingCount++; + } else { + decreasingCount++; + System.out.println("increasing count: " + increasingCount); + System.out.println("decreasing or the same count: " + decreasingCount); + System.out.println("Test passed: decreasing or the same instance count is observed"); + break; + } + previousInstanceCount = instanceCount; + } + + delayExecution(); + } + } + + /** + * This Logger call is leaking two different WeakReferences: + * - one in LogManager.LogNode + * - one in Logger.kids + */ + private static void callLogger() { + for (int i = 0; i < INSTANCE_COUNT; i++) { + java.util.logging.Logger.getLogger("logger-" + loggerCount); + if (++loggerCount >= 25000) { + // Limit the Logger namespace used by the test so the weak refs + // in LogManager.loggers that are being properly managed + // don't skew the counts by too much. + loggerCount = 0; + } + } + } + + /** + * This Logger call is leaking a WeakReference in Logger.kids + */ + private static void callAnonymousLogger() { + for (int i = 0; i < INSTANCE_COUNT; i++) { + java.util.logging.Logger.getAnonymousLogger(); + } + } + + /** + * 'vm.heapHisto("-live")' will request a full GC + */ + private static int getInstanceCountFromHeapHisto() throws AttachNotSupportedException, Exception { + int instanceCount = 0; + + HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine + .attach(Integer.toString(ProcessTools.getProcessId())); + try { + try (InputStream heapHistoStream = vm.heapHisto("-live"); + BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) { + String inputLine; + while ((inputLine = in.readLine()) != null) { + if (inputLine.contains(TARGET_CLASS)) { + instanceCount = Integer.parseInt(inputLine + .split("[ ]+")[2]); + System.out.println("instance count: " + instanceCount); + break; + } + } + } + } finally { + vm.detach(); + } + + assertGreaterThan(instanceCount, 0, "No instances of " + TARGET_CLASS + " are found"); + + return instanceCount; + } + + /** + * Delay for 1/10 of a second to avoid CPU saturation + */ + private static void delayExecution() { + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + // Ignore any exceptions + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java --- a/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/javax/management/monitor/CounterMonitorDeadlockTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 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 @@ -37,7 +37,6 @@ import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicInteger; -import javax.management.Attribute; import javax.management.JMX; import javax.management.MBeanServer; import javax.management.Notification; @@ -95,18 +94,16 @@ monitorProxy.setInitThreshold(100); monitorProxy.setGranularityPeriod(10L); // 10 ms monitorProxy.setNotify(true); + + final int initGetCount = observedProxy.getGetCount(); monitorProxy.start(); - final int initGetCount = observedProxy.getGetCount(); - int getCount; System.out.println("Checking GetCount, possible deadlock if timeout."); do { // 8038322. Until timeout of testing harness Thread.sleep(200); - } while ((getCount=observedProxy.getGetCount()) == initGetCount); + } while ((observedProxy.getGetCount()) == initGetCount); System.out.println("Done!"); - if (getCount <= initGetCount) - throw new Exception("Test failed: presumable deadlock"); // This won't show up as a deadlock in CTRL-\ or in // ThreadMXBean.findDeadlockedThreads(), because they don't // see that thread A is waiting for thread B (B.join()), and diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java Wed Jul 05 20:15:03 2017 +0200 @@ -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. + */ +package jdk.testlibrary; + +import java.util.function.Predicate; +/** + * A classloader, which using target classloader in case provided condition + * for class name is met, and using parent otherwise + */ +public class FilterClassLoader extends ClassLoader { + + private final ClassLoader target; + private final Predicate condition; + + public FilterClassLoader(ClassLoader target, ClassLoader parent, + Predicate condition) { + super(parent); + this.condition = condition; + this.target = target; + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (condition.test(name)) { + return target.loadClass(name); + } + return super.loadClass(name); + } +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 jdk.testlibrary; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * An url classloader, which trying to load class from provided URL[] first, + * and using parent classloader in case it failed + */ +public class ParentLastURLClassLoader extends URLClassLoader { + + public ParentLastURLClassLoader(URL urls[], ClassLoader parent) { + super(urls, parent); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + Class c = findClass(name); + if (c != null) { + return c; + } + } catch (ClassNotFoundException e) { + // ignore + } + return super.loadClass(name); + } +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Wed Jul 05 20:15:03 2017 +0200 @@ -28,6 +28,15 @@ private static final String dataModel = System.getProperty("sun.arch.data.model"); private static final String vmVersion = System.getProperty("java.vm.version"); private static final String osArch = System.getProperty("os.arch"); + private static final String vmName = System.getProperty("java.vm.name"); + + public static boolean isClient() { + return vmName.endsWith(" Client VM"); + } + + public static boolean isServer() { + return vmName.endsWith(" Server VM"); + } public static boolean is32bit() { return dataModel.equals("32"); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Wed Jul 05 20:15:03 2017 +0200 @@ -39,6 +39,7 @@ import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; /** * Common library for various test helper functions. @@ -271,25 +272,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; - } - - /** * 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" @@ -298,4 +280,50 @@ public static long adjustTimeout(long tOut) { return Math.round(tOut * Utils.TIMEOUT_FACTOR); } + + /** + * 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(); + } } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java --- a/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -29,13 +29,14 @@ */ import sun.awt.datatransfer.DataTransferer; - +import java.util.Comparator; +import sun.datatransfer.DataFlavorUtil; import java.awt.datatransfer.DataFlavor; public class DataFlavorComparatorTest { public static void main(String[] args) { - DataTransferer.DataFlavorComparator comparator = new DataTransferer.DataFlavorComparator(); + Comparator comparator = DataFlavorUtil.getDataFlavorComparator(); DataFlavor flavor1 = DataFlavor.imageFlavor; DataFlavor flavor2 = DataFlavor.selectionHtmlFlavor; if (comparator.compare(flavor1, flavor2) == 0) { diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java --- a/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/reflect/CallerSensitive/CallerSensitiveFinder.java Wed Jul 05 20:15:03 2017 +0200 @@ -26,20 +26,22 @@ import static com.sun.tools.classfile.ConstantPool.*; import java.io.File; import java.io.IOException; -import java.nio.file.FileVisitResult; +import java.io.UncheckedIOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; +import java.util.stream.Stream; /* * @test @@ -52,8 +54,10 @@ public class CallerSensitiveFinder { private static int numThreads = 3; private static boolean verbose = false; + private final ExecutorService pool; + public static void main(String[] args) throws Exception { - List classes = new ArrayList<>(); + Stream classes = null; String testclasses = System.getProperty("test.classes", "."); int i = 0; while (i < args.length) { @@ -65,25 +69,30 @@ if (!p.toFile().exists()) { throw new IllegalArgumentException(arg + " does not exist"); } - classes.add(p); + classes = Stream.of(p); } } - if (classes.isEmpty()) { - classes.addAll(PlatformClassPath.getJREClasses()); + + if (classes == null) { + classes = getPlatformClasses(); } - CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); + CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); + if (!errors.isEmpty()) { throw new RuntimeException(errors.size() + " caller-sensitive methods are missing @CallerSensitive annotation"); } } - private final List csMethodsMissingAnnotation = new ArrayList<>(); + private final List csMethodsMissingAnnotation = + Collections.synchronizedList(new ArrayList<>()); private final ReferenceFinder finder; public CallerSensitiveFinder() { this.finder = new ReferenceFinder(getFilter(), getVisitor()); + pool = Executors.newFixedThreadPool(numThreads); + } private ReferenceFinder.Filter getFilter() { @@ -123,11 +132,17 @@ }; } - public List run(List classes) throws IOException, InterruptedException, + public List run(Stream classes)throws IOException, InterruptedException, ExecutionException, ConstantPoolException { - ExecutorService pool = Executors.newFixedThreadPool(numThreads); - for (Path path : classes) { + classes.forEach(this::processPath); + waitForCompletion(); + pool.shutdown(); + return csMethodsMissingAnnotation; + } + + void processPath(Path path) { + try { ClassFileReader reader = ClassFileReader.newInstance(path); for (ClassFile cf : reader.getClassFiles()) { String classFileName = cf.getName(); @@ -137,10 +152,11 @@ // - visit and find method references matching the given method name pool.submit(getTask(cf)); } + } catch (IOException x) { + throw new UncheckedIOException(x); + } catch (ConstantPoolException x) { + throw new RuntimeException(x); } - waitForCompletion(); - pool.shutdown(); - return csMethodsMissingAnnotation; } private static final String CALLER_SENSITIVE_ANNOTATION = "Lsun/reflect/CallerSensitive;"; @@ -178,61 +194,34 @@ for (FutureTask t : tasks) { t.get(); } + if (tasks.isEmpty()) { + throw new RuntimeException("No classes found, or specified."); + } System.out.println("Parsed " + tasks.size() + " classfiles"); } - static class PlatformClassPath { - static List getJREClasses() throws IOException { - List result = new ArrayList(); - Path home = Paths.get(System.getProperty("java.home")); - - if (home.endsWith("jre")) { - // jar files in /jre/lib - // skip /lib - result.addAll(addJarFiles(home.resolve("lib"))); - } else if (home.resolve("lib").toFile().exists()) { - // either a JRE or a jdk build image - File classes = home.resolve("classes").toFile(); - if (classes.exists() && classes.isDirectory()) { - // jdk build outputdir - result.add(classes.toPath()); - } - // add other JAR files - result.addAll(addJarFiles(home.resolve("lib"))); - } else { - throw new RuntimeException("\"" + home + "\" not a JDK home"); - } - return result; - } + static Stream getPlatformClasses() throws IOException { + Path home = Paths.get(System.getProperty("java.home")); - static List addJarFiles(final Path root) throws IOException { - final List result = new ArrayList(); - final Path ext = root.resolve("ext"); - Files.walkFileTree(root, new SimpleFileVisitor() { - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) - throws IOException { - if (dir.equals(root) || dir.equals(ext)) { - return FileVisitResult.CONTINUE; - } else { - // skip other cobundled JAR files - return FileVisitResult.SKIP_SUBTREE; - } - } + // Either an exploded build or an image. + File classes = home.resolve("modules").toFile(); + if (classes.isDirectory()) { + return Stream.of(classes.toPath()); + } else { + return jrtPaths(); + } + } - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException { - File f = file.toFile(); - String fn = f.getName(); - // parse alt-rt.jar as well - if (fn.endsWith(".jar") && !fn.equals("jfxrt.jar")) { - result.add(file); - } - return FileVisitResult.CONTINUE; - } - }); - return result; + static Stream jrtPaths() { + FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/")); + Path root = jrt.getPath("/"); + + try { + return Files.walk(root) + .filter(p -> p.getNameCount() > 1) + .filter(p -> p.toString().endsWith(".class")); + } catch (IOException x) { + throw new UncheckedIOException(x); } } } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java --- a/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/reflect/CallerSensitive/MissingCallerSensitive.java Wed Jul 05 20:15:03 2017 +0200 @@ -34,11 +34,13 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; +import java.util.stream.Stream; + public class MissingCallerSensitive { public static void main(String[] args) throws Exception { String testclasses = System.getProperty("test.classes", "."); - List classes = new ArrayList<>(); - classes.add(Paths.get(testclasses, "MissingCallerSensitive.class")); + + Stream classes = Stream.of(Paths.get(testclasses, "MissingCallerSensitive.class")); CallerSensitiveFinder csfinder = new CallerSensitiveFinder(); List errors = csfinder.run(classes); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/security/pkcs11/Mac/MacKAT.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/pkcs11/Mac/MacKAT.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2003, 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 java.io.UnsupportedEncodingException; +import java.security.Provider; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 4846410 6313661 4963723 + * @summary Basic known-answer-test for Hmac algorithms + * @author Andreas Sterbenz + * @library .. + * @run main MacKAT + */ +public class MacKAT extends PKCS11Test { + + private final static byte[] ALONG, BLONG, BKEY, BKEY_20, DDDATA_50, + AAKEY_20, CDDATA_50, AAKEY_131; + + static { + ALONG = new byte[1024 * 128]; + Arrays.fill(ALONG, (byte)'a'); + BLONG = new byte[1024 * 128]; + Random random = new Random(12345678); + random.nextBytes(BLONG); + BKEY = new byte[128]; + random.nextBytes(BKEY); + BKEY_20 = new byte[20]; + Arrays.fill(BKEY_20, (byte) 0x0b); + DDDATA_50 = new byte[50]; + Arrays.fill(DDDATA_50, (byte) 0xdd); + AAKEY_20 = new byte[20]; + Arrays.fill(AAKEY_20, (byte) 0xaa); + CDDATA_50 = new byte[50]; + Arrays.fill(CDDATA_50, (byte) 0xcd); + AAKEY_131 = new byte[131]; + Arrays.fill(AAKEY_131, (byte) 0xaa); + } + + private final static Test[] tests = { + newMacTest("SslMacMD5", + ALONG, + "f4:ad:01:71:51:f6:89:56:72:a3:32:bf:d9:2a:f2:a5", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("SslMacMD5", + BLONG, + "34:1c:ad:a0:95:57:32:f8:8e:80:8f:ee:b2:d8:23:e5", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("SslMacSHA1", + ALONG, + "11:c1:71:2e:61:be:4b:cf:bc:6d:e2:4c:58:ae:27:30:0b:24:a4:87", + "23:ae:dd:61:87:6c:7a:45:47:2f:2c:8f:ea:64:99:3e:27:5f:97:a5"), + newMacTest("SslMacSHA1", + BLONG, + "84:af:57:0a:af:ef:16:93:90:50:da:88:f8:ad:1a:c5:66:6c:94:d0", + "9b:bb:e2:aa:9b:28:1c:95:0e:ea:30:21:98:a5:7e:31:9e:bf:5f:51"), + newMacTest("HmacMD5", + ALONG, + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacMD5", + BLONG, + "6c:22:79:bb:34:9e:da:f4:f5:cf:df:0c:62:3d:59:e0", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacMD5", + BLONG, + "e6:ad:00:c9:49:6b:98:fe:53:a2:b9:2d:7d:41:a2:03", + BKEY), + newMacTest("HmacSHA1", + ALONG, + "9e:b3:6e:35:fa:fb:17:2e:2b:f3:b0:4a:9d:38:83:c4:5f:6d:d9:00", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA1", + BLONG, + "80:2d:5b:ea:08:df:a4:1f:e5:3e:1c:fa:fc:ad:dd:31:da:15:60:2c", + "76:00:4a:72:98:9b:65:ec:2e:f1:43:c4:65:4a:13:71"), + newMacTest("HmacSHA1", + BLONG, + "a2:fa:2a:85:18:0e:94:b2:a5:e2:17:8b:2a:29:7a:95:cd:e8:aa:82", + BKEY), + newMacTest("HmacSHA256", + ALONG, + "3f:6d:08:df:0c:90:b0:e9:ed:13:4a:2e:c3:48:1d:3d:3e:61:2e:f1:" + + "30:c2:63:c4:58:57:03:c2:cb:87:15:07", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA256", + BLONG, + "e2:4e:a3:b9:0b:b8:99:e4:71:cf:ca:9f:f8:4e:f0:34:8b:19:9f:33:" + + "4b:1a:b7:13:f7:c8:57:92:e3:03:74:78", + BKEY), + newMacTest("HmacSHA384", + ALONG, + "d0:f0:d4:54:1c:0a:6d:81:ed:15:20:d7:0c:96:06:61:a0:ff:c9:ff:" + + "91:e9:a0:cd:e2:45:64:9d:93:4c:a9:fa:89:ae:c0:90:e6:" + + "0b:a1:a0:56:80:57:3b:ed:4b:b0:71", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA384", + BLONG, + "75:c4:ca:c7:f7:58:9d:d3:23:b1:1b:5c:93:2d:ec:7a:03:dc:8c:eb:" + + "8d:fe:79:46:4f:30:e7:99:62:de:44:e2:38:95:0e:79:91:" + + "78:2f:a4:05:0a:f0:17:10:38:a1:8e", + BKEY), + newMacTest("HmacSHA512", + ALONG, + "41:ea:4c:e5:31:3f:7c:18:0e:5e:95:a9:25:0a:10:58:e6:40:53:88:" + + "82:4f:5a:da:6f:29:de:04:7b:8e:d7:ed:7c:4d:b8:2a:48:" + + "2d:17:2a:2d:59:bb:81:9c:bf:33:40:04:77:44:fb:45:25:" + + "1f:fd:b9:29:f4:a6:69:a3:43:6f", + "1b:34:61:29:05:0d:73:db:25:d0:dd:64:06:29:f6:8a"), + newMacTest("HmacSHA512", + BLONG, + "fb:cf:4b:c6:d5:49:5a:5b:0b:d9:2a:32:f5:fa:68:d2:68:a4:0f:ae:" + + "53:fc:49:12:e6:1d:53:cf:b2:cb:c5:c5:f2:2d:86:bd:14:" + + "61:30:c3:a6:6f:44:1f:77:9b:aa:a1:22:48:a9:dd:d0:45:" + + "86:d1:a1:82:53:13:c4:03:06:a3", + BKEY), + + // Test vectors From RFC 4231 + newMacTest("HmacSHA224", + bytes("Hi There"), + "89:6f:b1:12:8a:bb:df:19:68:32:10:7c:d4:9d:f3:3f:47:b4:b1:16:" + + "99:12:ba:4f:53:68:4b:22", + BKEY_20), + newMacTest("HmacSHA224", + bytes("what do ya want for nothing?"), + "a3:0e:01:09:8b:c6:db:bf:45:69:0f:3a:7e:9e:6d:0f:8b:be:a2:a3:" + + "9e:61:48:00:8f:d0:5e:44", + bytes("Jefe")), + newMacTest("HmacSHA224", + DDDATA_50, + "7f:b3:cb:35:88:c6:c1:f6:ff:a9:69:4d:7d:6a:d2:64:93:65:b0:c1:" + + "f6:5d:69:d1:ec:83:33:ea", + AAKEY_20), + newMacTest("HmacSHA224", + CDDATA_50, + "6c:11:50:68:74:01:3c:ac:6a:2a:bc:1b:b3:82:62:7c:ec:6a:90:d8:" + + "6e:fc:01:2d:e7:af:ec:5a", + "01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:" + + "15:16:17:18:19"), + newMacTest("HmacSHA224", + bytes("Test Using Larger Than Block-Size Key - Hash Key First"), + "95:e9:a0:db:96:20:95:ad:ae:be:9b:2d:6f:0d:bc:e2:d4:99:f1:12:" + + "f2:d2:b7:27:3f:a6:87:0e", + AAKEY_131), + newMacTest("HmacSHA224", + bytes("This is a test using a larger than block-size key and " + + "a larger than block-size data. The key needs to be " + + "hashed before being used by the HMAC algorithm."), + "3a:85:41:66:ac:5d:9f:02:3f:54:d5:17:d0:b3:9d:bd:94:67:70:db:" + + "9c:2b:95:c9:f6:f5:65:d1", + AAKEY_131), + }; + + public static void main(String[] args) throws Exception { + main(new MacKAT()); + } + + @Override + public void main(Provider p) throws Exception { + long start = System.currentTimeMillis(); + + List algorithms = getSupportedAlgorithms("Mac", "", p); + for (Test test : tests) { + if(!algorithms.contains(test.getAlg())) { + continue; + } + test.run(p); + } + + System.out.println("All tests passed"); + long stop = System.currentTimeMillis(); + System.out.println("Done (" + (stop - start) + " ms)."); + } + + private static byte[] bytes(String s) { + try { + return s.getBytes("UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + String key) { + return new MacTest(alg, input, parse(macvalue), parse(key)); + } + + private static Test newMacTest(String alg, byte[] input, String macvalue, + byte[] key) { + return new MacTest(alg, input, parse(macvalue), key); + } + + interface Test { + void run(Provider p) throws Exception; + String getAlg(); + } + + static class MacTest implements Test { + private final String alg; + private final byte[] input; + private final byte[] macvalue; + private final byte[] key; + + MacTest(String alg, byte[] input, byte[] macvalue, byte[] key) { + this.alg = alg; + this.input = input; + this.macvalue = macvalue; + this.key = key; + } + + @Override + public String getAlg() { + return alg; + } + + @Override + public void run(Provider p) throws Exception { + Mac mac = Mac.getInstance(alg, p); + SecretKey keySpec = new SecretKeySpec(key, alg); + mac.init(keySpec); + mac.update(input); + byte[] macv = mac.doFinal(); + if (Arrays.equals(macvalue, macv) == false) { + System.out.println("Mac test for " + alg + " failed:"); + if (input.length < 256) { + System.out.println("input: " + + PKCS11Test.toString(input)); + } + System.out.println("key: " + PKCS11Test.toString(key)); + System.out.println("macvalue: " + + PKCS11Test.toString(macvalue)); + System.out.println("calculated: " + PKCS11Test.toString(macv)); + throw new Exception("Mac test for " + alg + " failed"); + } + System.out.println("passed: " + alg); + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/security/pkcs11/Mac/MacSameTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 1998, 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 java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Provider; +import java.security.SecureRandom; +import java.util.List; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * @test + * @bug 8048603 + * @summary Check if doFinal and update operation result in same Mac + * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin + * @library .. + * @run main MacSameTest + */ +public class MacSameTest extends PKCS11Test { + + private static final int MESSAGE_SIZE = 25; + private static final int OFFSET = 5; + private static final int KEY_SIZE = 70; + + /** + * Initialize a message, instantiate a Mac object, + * initialize the object with a SecretKey, + * feed the message into the Mac object + * all at once and get the output MAC as result1. + * Reset the Mac object, chop the message into three pieces, + * feed into the Mac object sequentially, and get the output MAC as result2. + * Finally, compare result1 and result2 and see if they are the same. + * + * @param args the command line arguments + */ + public static void main(String[] args) throws Exception { + main(new MacSameTest()); + } + + @Override + public void main(Provider p) { + List algorithms = getSupportedAlgorithms("Mac", "Hmac", p); + boolean success = true; + for (String alg : algorithms) { + try { + doTest(alg, p); + } catch (Exception e) { + System.out.println("Unexpected exception: " + e); + e.printStackTrace(); + success = false; + } + } + + if (!success) { + throw new RuntimeException("Test failed"); + } + } + + private void doTest(String algo, Provider provider) + throws NoSuchAlgorithmException, NoSuchProviderException, + InvalidKeyException { + System.out.println("Test " + algo); + Mac mac; + try { + mac = Mac.getInstance(algo, provider); + } catch (NoSuchAlgorithmException nsae) { + if ("SunPKCS11-Solaris".equals(provider.getName())) { + // depending on Solaris configuration, + // it can support HMAC or not with Mac + System.out.println("Expected NoSuchAlgorithmException thrown: " + + nsae); + return; + } + throw nsae; + } + + byte[] plain = new byte[MESSAGE_SIZE]; + for (int i = 0; i < MESSAGE_SIZE; i++) { + plain[i] = (byte) (i % 256); + } + + byte[] tail = new byte[plain.length - OFFSET]; + System.arraycopy(plain, OFFSET, tail, 0, tail.length); + + SecureRandom srdm = new SecureRandom(); + byte[] keyVal = new byte[KEY_SIZE]; + srdm.nextBytes(keyVal); + SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC"); + + mac.init(keySpec); + byte[] result1 = mac.doFinal(plain); + + mac.reset(); + mac.update(plain[0]); + mac.update(plain, 1, OFFSET - 1); + byte[] result2 = mac.doFinal(tail); + + if (!java.util.Arrays.equals(result1, result2)) { + throw new RuntimeException("result1 and result2 are not the same"); + } + } + +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/security/pkcs11/PKCS11Test.java --- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 20:15:03 2017 +0200 @@ -582,4 +582,21 @@ return r; } + /** + * Returns supported algorithms of specified type. + */ + static List getSupportedAlgorithms(String type, String alg, + Provider p) { + // prepare a list of supported algorithms + List algorithms = new ArrayList<>(); + Set services = p.getServices(); + for (Provider.Service service : services) { + if (service.getType().equals(type) + && service.getAlgorithm().startsWith(alg)) { + algorithms.add(service.getAlgorithm()); + } + } + return algorithms; + } + } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/security/x509/Extensions/DefaultCriticality.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/x509/Extensions/DefaultCriticality.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,50 @@ +/* + * 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 + * @summary Change default criticality of policy mappings and policy constraints + certificate extensions + * @bug 8059916 + */ + +import sun.security.x509.PolicyConstraintsExtension; +import sun.security.x509.PolicyMappingsExtension; + +public class DefaultCriticality { + public static void main(String [] args) throws Exception { + PolicyConstraintsExtension pce = new PolicyConstraintsExtension(-1,-1); + if (!pce.isCritical()) { + throw new Exception("PolicyConstraintsExtension should be " + + "critical by default"); + } + + PolicyMappingsExtension pme = new PolicyMappingsExtension(); + if (!pme.isCritical()) { + throw new Exception("PolicyMappingsExtension should be " + + "critical by default"); + } + + System.out.println("Test passed."); + } +} diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/tools/common/CommonTests.sh --- a/jdk/test/sun/tools/common/CommonTests.sh Thu Jan 15 13:09:43 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2010, 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 6964018 -# @summary Unit test for common tools infrastructure. -# -# @build SimpleApplication SleeperApplication ShutdownSimpleApplication -# @run shell CommonTests.sh - -. ${TESTSRC}/CommonSetup.sh -. ${TESTSRC}/ApplicationSetup.sh - -# hope for the best: -status=0 - - -# Test program path constants from CommonSetup.sh: -# -for name in JAVA JHAT JINFO JMAP JPS JSTACK; do - eval value=$`echo $name` - - echo "INFO: $name=$value" - if [ -x "$value" ]; then - echo "INFO: '$value' is executable." - else - echo "ERROR: '$value' is not executable." >&2 - status=1 - fi -done - - -# Display flag values from CommonSetup.sh: -# -for name in isCygwin isMKS isLinux isSolaris isUnknownOS isWindows; do - eval value=$`echo $name` - echo "INFO: flag $name=$value" -done - - -# Test OS constant from CommonSetup.sh: -# -if [ -z "$OS" ]; then - echo "ERROR: OS constant cannot be empty." >&2 - status=1 -fi - - -# Display the PATTERN_EOL value: -# -echo "INFO: PATTERN_EOL="`echo "$PATTERN_EOL" | od -c` - - -# Test PATTERN_EOL with 'grep' for a regular line. -# -TESTOUT="${TESTCLASSES}/testout.grep_reg_line_eol" -set +e -echo 'regular line' | grep "line${PATTERN_EOL}" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for regular line with grep." -else - echo "ERROR: PATTERN_EOL does not work for regular line with grep." >&2 - status=1 -fi - - -if $isWindows; then - # Test PATTERN_EOL with 'grep' for a CR line. - # - TESTOUT="${TESTCLASSES}/testout.grep_cr_line_eol" - set +e - echo 'CR line ' | grep "line${PATTERN_EOL}" > "$TESTOUT" - set -e - if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for CR line with grep." - else - echo "ERROR: PATTERN_EOL does not work for CR line with grep." >&2 - status=1 - fi -fi - - -# Test PATTERN_EOL with 'sed' for a regular line. -# -TESTOUT="${TESTCLASSES}/testout.sed_reg_line_eol" -echo 'regular line' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for regular line with sed." -else - echo "ERROR: PATTERN_EOL does not work for regular line with sed." >&2 - status=1 -fi - - -if $isWindows; then - # Test PATTERN_EOL with 'sed' for a CR line. - # - TESTOUT="${TESTCLASSES}/testout.sed_cr_line_eol" - echo 'CR line ' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" - if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_EOL works for CR line with sed." - else - echo "ERROR: PATTERN_EOL does not work for CR line with sed." >&2 - status=1 - fi -fi - - -# Display the PATTERN_WS value: -# -echo "INFO: PATTERN_WS="`echo "$PATTERN_WS" | od -c` - - -# Test PATTERN_WS with 'grep' for a blank. -# -TESTOUT="${TESTCLASSES}/testout.grep_blank" -set +e -echo 'blank: ' | grep "$PATTERN_WS" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for blanks with grep." -else - echo "ERROR: PATTERN_WS does not work for blanks with grep." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'grep' for a tab. -# -TESTOUT="${TESTCLASSES}/testout.grep_tab" -set +e -echo 'tab: ' | grep "$PATTERN_WS" > "$TESTOUT" -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for tabs with grep." -else - echo "ERROR: PATTERN_WS does not work for tabs with grep." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'sed' for a blank. -# -TESTOUT="${TESTCLASSES}/testout.sed_blank" -echo 'blank: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for blanks with sed." -else - echo "ERROR: PATTERN_WS does not work for blanks with sed." >&2 - status=1 -fi - - -# Test PATTERN_WS with 'sed' for a tab. -# -TESTOUT="${TESTCLASSES}/testout.sed_tab" -echo 'tab: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" -if [ -s "$TESTOUT" ]; then - echo "INFO: PATTERN_WS works for tabs with sed." -else - echo "ERROR: PATTERN_WS does not work for tabs with sed." >&2 - status=1 -fi - - -# Test startApplication and use PORTFILE for coordination -# The app sleeps for 30 seconds. -# -PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication SleeperApplication "${PORTFILE}" 30 - - -# Test appJavaPid in "ps" cmd output. -# -TESTOUT="${TESTCLASSES}/testout.ps_app" -set +e -if $isCygwin; then - # On Cygwin, appJavaPid is the Windows pid for the Java process - # and appOtherPid is the Cygwin pid for the Java process. - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -fi -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: begin appJavaPid=$appJavaPid in 'ps' cmd output:" - cat "$TESTOUT" - echo "INFO: end appJavaPid=$appJavaPid in 'ps' cmd output." -else - echo "ERROR: 'ps' cmd should show appJavaPid=$appJavaPid." >&2 - status=1 -fi - -if [ -n "$appOtherPid" ]; then - # Test appOtherPid in "ps" cmd output, if we have one. - # - TESTOUT="${TESTCLASSES}/testout.ps_other" - set +e - if $isCygwin; then - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appOtherPid}${PATTERN_WS}" > "$TESTOUT" - else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appOtherPid}${PATTERN_WS}" > "$TESTOUT" - fi - set -e - if [ -s "$TESTOUT" ]; then - echo "INFO: begin appOtherPid=$appOtherPid in 'ps' cmd output:" - cat "$TESTOUT" - echo "INFO: end appOtherPid=$appOtherPid in 'ps' cmd output." - else - echo "ERROR: 'ps' cmd should show appOtherPid=$appOtherPid." >&2 - status=1 - fi -fi - - -# Test stopApplication and PORTFILE for coordination -# -stopApplication "${PORTFILE}" - - -# Test application still running after stopApplication. -# -# stopApplication just lets the app know that it can stop, but the -# app might still be doing work. This test just demonstrates that -# fact and doesn't fail if the app is already done. -# -TESTOUT="${TESTCLASSES}/testout.after_stop" -set +e -if $isCygwin; then - # On Cygwin, appJavaPid is the Windows pid for the Java process - # and appOtherPid is the Cygwin pid for the Java process. - ps -p "$appOtherPid" \ - | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -else - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" -fi -set -e -if [ -s "$TESTOUT" ]; then - echo "INFO: it is okay for appJavaPid=$appJavaPid to still be running" \ - "after stopApplication() is called." - echo "INFO: begin 'after_stop' output:" - cat "$TESTOUT" - echo "INFO: end 'after_stop' output." -fi - - -# Test waitForApplication -# -# The app might already be gone so this function shouldn't generate -# a fatal error in either call. -# -waitForApplication - -if [ $isWindows = false ]; then - # Windows can recycle pids quickly so we can't use this test there - TESTOUT="${TESTCLASSES}/testout.after_kill" - set +e - # output only pid and comm columns to avoid mismatches - ps -eo pid,comm \ - | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" - set -e - if [ -s "$TESTOUT" ]; then - echo "ERROR: 'ps' cmd should not show appJavaPid." >&2 - echo "ERROR: begin 'after_kill' output:" >&2 - cat "$TESTOUT" >&2 - echo "ERROR: end 'after_kill' output." >&2 - status=1 - else - echo "INFO: 'ps' cmd does not show appJavaPid after" \ - "waitForApplication() is called." - fi -fi - - -# Test killApplication -# -# The app is already be gone so this function shouldn't generate -# a fatal error. -# -killApplication - -exit $status diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/tools/jcmd/TestJcmdDefaults.java --- a/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java Wed Jul 05 20:15:03 2017 +0200 @@ -25,6 +25,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -95,11 +98,11 @@ } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/tools/jcmd/TestJcmdSanity.java --- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Wed Jul 05 20:15:03 2017 +0200 @@ -25,6 +25,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -160,11 +163,11 @@ } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "help_help.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "help_help.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/sun/tools/jps/JpsHelper.java --- a/jdk/test/sun/tools/jps/JpsHelper.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/sun/tools/jps/JpsHelper.java Wed Jul 05 20:15:03 2017 +0200 @@ -28,6 +28,9 @@ 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 java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -189,11 +192,11 @@ */ public static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { String testSrc = System.getProperty("test.src", "?"); - File file = new File(testSrc, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(testSrc, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } private static File getManifest(String className) throws IOException { diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/tools/launcher/Arrrghs.java --- a/jdk/test/tools/launcher/Arrrghs.java Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/tools/launcher/Arrrghs.java Wed Jul 05 20:15:03 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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,12 +30,10 @@ * @run main/othervm Arrrghs */ -import java.io.BufferedReader; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -48,9 +46,6 @@ private Arrrghs(){} /** * This class provides various tests for arguments processing. - * A group of tests to ensure that arguments are passed correctly to - * a child java process upon a re-exec, this typically happens when - * a version other than the one being executed is requested by the user. * * History: these set of tests were part of Arrrghs.sh. The MKS shell * implementations were notoriously buggy. Implementing these tests purely @@ -58,12 +53,6 @@ * */ - // The version string to force a re-exec - final static String VersionStr = "-version:1.1+"; - - // The Cookie or the pattern we match in the debug output. - final static String Cookie = "ReExec Args: "; - /* * SIGH, On Windows all strings are quoted, we need to unwrap it */ @@ -78,122 +67,6 @@ return in; } - /* - * This method detects the cookie in the output stream of the process. - */ - private boolean detectCookie(InputStream istream, - String expectedArguments) throws IOException { - BufferedReader rd = new BufferedReader(new InputStreamReader(istream)); - boolean retval = false; - - String in = rd.readLine(); - while (in != null) { - if (debug) System.out.println(in); - if (in.startsWith(Cookie)) { - String detectedArgument = removeExtraQuotes(in.substring(Cookie.length())); - if (expectedArguments.equals(detectedArgument)) { - retval = true; - } else { - System.out.println("Error: Expected Arguments\t:'" + - expectedArguments + "'"); - System.out.println(" Detected Arguments\t:'" + - detectedArgument + "'"); - } - // Return the value asap if not in debug mode. - if (!debug) { - rd.close(); - istream.close(); - return retval; - } - } - in = rd.readLine(); - } - return retval; - } - - private boolean doReExecTest0(ProcessBuilder pb, String expectedArguments) { - boolean retval = false; - try { - pb.redirectErrorStream(true); - Process p = pb.start(); - retval = detectCookie(p.getInputStream(), expectedArguments); - p.waitFor(); - p.destroy(); - } catch (Exception ex) { - ex.printStackTrace(); - throw new RuntimeException(ex.getMessage()); - } - return retval; - } - - /** - * This method returns true if the expected and detected arguments are the same. - * Quoting could cause dissimilar testArguments and expected arguments. - */ - int doReExecTest(String testArguments, String expectedPattern) { - ProcessBuilder pb = new ProcessBuilder(javaCmd, - VersionStr, testArguments); - - Map env = pb.environment(); - env.put(JLDEBUG_KEY, "true"); - return doReExecTest0(pb, testArguments) ? 0 : 1; - } - - /** - * A convenience method for identical test pattern and expected arguments - */ - int doReExecTest(String testPattern) { - return doReExecTest(testPattern, testPattern); - } - - @Test - void testQuoteParsingThroughReExec() { - /* - * Tests for 6214916 - * These tests require that a JVM (any JVM) be installed in the system registry. - * If none is installed, skip this test. - */ - TestResult tr = doExec(javaCmd, VersionStr, "-version"); - if (!tr.isOK()) { - System.err.println("Warning:Argument Passing Tests were skipped, " + - "no java found in system registry."); - return; - } - - // Basic test - testExitValue += doReExecTest("-a -b -c -d"); - - // Basic test with many spaces - testExitValue += doReExecTest("-a -b -c -d"); - - // Quoted whitespace does matter ? - testExitValue += doReExecTest("-a \"\"-b -c\"\" -d"); - - - // Escaped quotes outside of quotes as literals - testExitValue += doReExecTest("-a \\\"-b -c\\\" -d"); - - // Check for escaped quotes inside of quotes as literal - testExitValue += doReExecTest("-a \"-b \\\"stuff\\\"\" -c -d"); - - // A quote preceeded by an odd number of slashes is a literal quote - testExitValue += doReExecTest("-a -b\\\\\\\" -c -d"); - - // A quote preceeded by an even number of slashes is a literal quote - // see 6214916. - testExitValue += doReExecTest("-a -b\\\\\\\\\" -c -d"); - - // Make sure that whitespace doesn't interfere with the removal of the - // appropriate tokens. (space-tab-space preceeds -jre-restict-search). - testExitValue += doReExecTest("-a -b \t -jre-restrict-search -c -d", "-a -b -c -d"); - - // Make sure that the mJRE tokens being stripped, aren't stripped if - // they happen to appear as arguments to the main class. - testExitValue += doReExecTest("foo -version:1.1+"); - - System.out.println("Completed arguments quoting tests with " - + testExitValue + " errors"); - } // the pattern we hope to see in the output static final Pattern ArgPattern = Pattern.compile("\\s*argv\\[[0-9]*\\].*=.*"); diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/tools/launcher/MultipleJRE.sh --- a/jdk/test/tools/launcher/MultipleJRE.sh Thu Jan 15 13:09:43 2015 -0800 +++ b/jdk/test/tools/launcher/MultipleJRE.sh Wed Jul 05 20:15:03 2017 +0200 @@ -90,36 +90,6 @@ } # -# Shell routine to ensure help page does not include mjre options -# -TestHelp() { - mess="`$JAVA -help 2>&1`" - # make sure it worked - if [ $? -ne 0 ]; then - echo "java -help failed ????" - exit 1 - fi - - echo $mess | grep '\-version:' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option version:" - exit 1 - fi - - echo $mess | grep '\-jre-restrict-search' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option jre-restrict-search" - exit 1 - fi - - echo $mess | grep '\-no-jre-restrict-search' > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "help message contains obsolete option no-jre-restrict-search" - exit 1 - fi -} - -# # Just as the name says. We sprinkle these in the appropriate location # in the test file system and they just say who they are pretending to be. # @@ -461,33 +431,4 @@ LaunchVM "" "${RELEASE}" fi -# -# Now test specification of mJRE -# -# In some cases this should result in failure of the command, -# in some cases, a warning messages, with the command succeeding. -# - - # Commandline use of "-version:" should fail - # with a message containing "no longer supported" - LaunchVM "-version:1.10+" "Error: Specifying an alternate JDK/JRE" - LaunchVM "-version:prettymuchanything" "Error: Specifying an alternate JDK/JRE" - - # Commandline use of "-jre-restrict-search" should now fail - LaunchVM "-jre-restrict-search" "\-jre\-no\-restrict\-search are also no longer valid" - # Commandline use of "-jre-no-restrict-search" should now fail - LaunchVM "-jre-no-restrict-search" "\-jre\-no\-restrict\-search are also no longer valid" - - - # mJRE directives to use a specific version should be flagged - # with a warning, but the jar should be executed with the - # current jre - CreateFullJar "junk request" "" - LaunchVM "" "${RELEASE}" - # Going to silently ignore JRE-Version setting in jar file manifest - #LaunchVM "" "warning: The jarfile JRE-Version" - - # Verify help does not contain obsolete options - TestHelp - exit 0 diff -r c9c4b9563018 -r 0df4b242ce77 jdk/test/tools/launcher/MultipleJRERemoved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/tools/launcher/MultipleJRERemoved.java Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,212 @@ +/* + * 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 8067437 + * @summary Verify Multiple JRE version support has been removed. + * @build TestHelper + * @run main MultipleJRERemoved + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.util.*; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; + +public class MultipleJRERemoved extends TestHelper { + + public static final String VERSION_JAR = "version.jar"; + public static final String PRINT_VERSION_CLASS = "PrintVersion"; + private final File javaFile = new File(PRINT_VERSION_CLASS + ".java"); + private final File clsFile = new File(PRINT_VERSION_CLASS + ".class"); + + private MultipleJRERemoved() { + } + + /** + * @param args the command line arguments + * @throws java.io.FileNotFoundException + */ + public static void main(String[] args) throws Exception { + MultipleJRERemoved a = new MultipleJRERemoved(); + a.run(args); + } + + /** + * Check all combinations of flags: "-version:", "-jre-restrict-search", "-jre-no-restrict-search". Test expects to see errors. + */ + @Test + public void allFlagCombinations() throws IOException { + final Pattern newLine = Pattern.compile("\n"); + createJar(Collections.emptyMap()); + + for (Flag flag1 : Flag.values()) { + for (Flag flag2 : Flag.values()) { + for (Flag flag3 : Flag.values()) { + List flags = Stream.of(flag1, flag2, flag3) + .filter(f -> !Flag.EMPTY.equals(f)) + .collect(Collectors.toList()); + + if (flags.size() == 0) continue; + + List flagValues = flags.stream() + .map(Flag::value) + .collect(Collectors.toList()); + + List errorMessages = flags.stream() + .map(Flag::errorMessage) + .flatMap(newLine::splitAsStream) + .collect(Collectors.toList()); + + List jarCmd = new ArrayList<>(); + jarCmd.add(javaCmd); + jarCmd.addAll(flagValues); + jarCmd.add("-jar"); + jarCmd.add("version.jar"); + + check(jarCmd, errorMessages); + + List cmd = new ArrayList<>(); + cmd.add(javaCmd); + cmd.addAll(flagValues); + cmd.add(PRINT_VERSION_CLASS); + + check(cmd, errorMessages); + } + } + } + } + + private void check(List cmd, List errorMessages) { + TestResult tr = doExec(cmd.toArray(new String[cmd.size()])); + tr.checkNegative(); + tr.isNotZeroOutput(); + errorMessages.forEach(tr::contains); + + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("test case: failed\n" + cmd); + } + } + + /** + * Verifies that java -help output doesn't contain information about "mJRE" flags. + */ + @Test + public void javaHelp() { + TestResult tr = doExec(javaCmd, "-help"); + tr.checkPositive(); + tr.isNotZeroOutput(); + tr.notContains("-version:"); + tr.notContains("-jre-restrict-search"); + tr.notContains("-jre-no-restrict-search"); + tr.notContains("-no-jre-restrict-search"); //it's not a typo in flag name. + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("Failed. java -help output contains obsolete flags.\n"); + } + } + + /** + * Verifies that java -jar version.jar output ignores "mJRE" manifest directives. + */ + @Test + public void manifestDirectives() throws IOException { + Map manifest = new TreeMap<>(); + manifest.put("JRE-Version", "1.8"); + manifest.put("JRE-Restrict-Search", "1.8"); + createJar(manifest); + + TestResult tr = doExec(javaCmd, "-jar", VERSION_JAR); + tr.checkPositive(); + tr.contains(System.getProperty("java.version")); + if (!tr.testStatus) { + System.out.println(tr); + throw new RuntimeException("Failed.\n"); + } + } + + private void emitFile() throws IOException { + List scr = new ArrayList<>(); + scr.add("public class PrintVersion {"); + scr.add(" public static void main(String... args) {"); + scr.add(" System.out.println(System.getProperty(\"java.version\"));"); + scr.add(" }"); + scr.add("}"); + createFile(javaFile, scr); + compile(javaFile.getName()); + } + + private void createJar(Map manifestAttributes) throws IOException { + emitFile(); + + Manifest manifest = new Manifest(); + final Attributes mainAttributes = manifest.getMainAttributes(); + mainAttributes.putValue("Manifest-Version", "1.0"); + mainAttributes.putValue("Main-Class", PRINT_VERSION_CLASS); + manifestAttributes.forEach(mainAttributes::putValue); + + try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(VERSION_JAR), manifest)) { + jar.putNextEntry(new ZipEntry(PRINT_VERSION_CLASS + ".class")); + jar.write(Files.readAllBytes(clsFile.toPath())); + jar.closeEntry(); + } finally { + javaFile.delete(); + } + } + + private enum Flag { + EMPTY("", ""), + VERSION("-version:1.9", "Error: Specifying an alternate JDK/JRE version is no longer supported.\n" + + "The use of the flag '-version:' is no longer valid.\n" + + "Please download and execute the appropriate version."), + JRE_RESTRICT_SEARCH("-jre-restrict-search", "Error: Specifying an alternate JDK/JRE is no longer supported.\n" + + "The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."), + JRE_NO_RESTRICT_SEARCH("-jre-no-restrict-search", "Error: Specifying an alternate JDK/JRE is no longer supported.\n" + + "The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."); + private final String flag; + private final String errorMessage; + + Flag(String flag, String errorMessage) { + this.flag = flag; + this.errorMessage = errorMessage; + } + + String value() { + return flag; + } + + String errorMessage() { + return errorMessage; + } + } +} diff -r c9c4b9563018 -r 0df4b242ce77 make/Images.gmk --- a/make/Images.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/Images.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/MakeHelpers.gmk --- a/make/MakeHelpers.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/MakeHelpers.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/ModuleWrapper.gmk --- a/make/ModuleWrapper.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/ModuleWrapper.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/common/JavaCompilation.gmk --- a/make/common/JavaCompilation.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/common/JavaCompilation.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/common/NativeCompilation.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/common/SetupJavaCompilers.gmk --- a/make/common/SetupJavaCompilers.gmk Thu Jan 15 13:09:43 2015 -0800 +++ b/make/common/SetupJavaCompilers.gmk Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 make/jprt.properties --- a/make/jprt.properties Thu Jan 15 13:09:43 2015 -0800 +++ b/make/jprt.properties Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 nashorn/.hgtags --- a/nashorn/.hgtags Thu Jan 15 13:09:43 2015 -0800 +++ b/nashorn/.hgtags Wed Jul 05 20:15:03 2017 +0200 @@ -279,3 +279,4 @@ 8ae8dff2a28f3b8831cce97ae0c7a957c5dc650a jdk9-b43 50ee576062726e536d1bb9a5eadd8fd4470128fc jdk9-b44 3c2bbeda038aef7061455fec604db7d8a342fac5 jdk9-b45 +2ecf0a617f0f9af1ffd278a0c70e76f1946ce773 jdk9-b46 diff -r c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 13:09:43 2015 -0800 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 nashorn/test/script/basic/JDK-8020324.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Thu Jan 15 13:09:43 2015 -0800 +++ b/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -0,0 +1,10 @@ +[object global] +[object global] +34.23 +hello +false +[object global] +[object Object] +foo +[] +{foo=bar} diff -r c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Jan 15 13:09:43 2015 -0800 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 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 Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 test/lib/sun/hotspot/WhiteBox.java --- a/test/lib/sun/hotspot/WhiteBox.java Thu Jan 15 13:09:43 2015 -0800 +++ b/test/lib/sun/hotspot/WhiteBox.java Wed Jul 05 20:15:03 2017 +0200 @@ -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 c9c4b9563018 -r 0df4b242ce77 test/lib/sun/hotspot/code/BlobType.java --- a/test/lib/sun/hotspot/code/BlobType.java Thu Jan 15 13:09:43 2015 -0800 +++ b/test/lib/sun/hotspot/code/BlobType.java Wed Jul 05 20:15:03 2017 +0200 @@ -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); + } }